核间中断测试

1)假设系统有N个核,创建N个线程,分别绑定到核0...(N-1);

2)所有线程通过同一个互斥锁[FIFO方式唤醒]进行阻塞和唤醒操作,并对自己被唤醒计数;

3)核间随机唤醒;执行一段时间,至少N分钟



#include "testfrmw.h"
#include "smp_test.h"


volatile int ipi_count[CPU_NUM] = {0};
volatile int ipi_count_temp[CPU_NUM] = {0};
pthread_mutex_t ipi_thread_mutex;
pthread_t ipi_t_id[CPU_NUM];
static smp_arg_stru arg_stru_arry[CPU_NUM];


int fail_flag = 0;
int ipi_main_ret = 0;


static int permanent_thread_init(void)
{
    int id;
    int ret;


    ret = pthread_mutex_init(&ipi_thread_mutex,NULL);
    if(ret)
    {
        printf("pthread_mutex_init fail!\n");
        return ret;
    }


    //每核创建一个常驻线程
    for(id = 0; id < CPU_NUM; id++)
    {
        arg_stru_arry[id].pcount = &ipi_count[id];
        arg_stru_arry[id].pmutex = &ipi_thread_mutex;


        ret = smp_pthread_init(&ipi_t_id[id],&arg_stru_arry[id],id);
        if(ret)
        {
            printf("smp_base_init fail!\n");
            return ret;
        }
    }


    return 0;
}


static int check_result(void)
{
    int id;
    int gap = ipi_count_temp[0]/10;


    for(id = 1; id < CPU_NUM; id++)
    {
        if(absolute_value(ipi_count_temp[id] - ipi_count_temp[0]) > gap)
        {
            printf("check_result fail on cpu%d\n",id);
            return 1;
        }
    }
    return 0;
}


void get_ipi_test_count()
{
    int id;


    memcpy((void*)ipi_count_temp,(void*)ipi_count,sizeof(ipi_count));


    usleep(TEST_UNIT*100000);


    for(id = 0; id < CPU_NUM; id++)
        ipi_count_temp[id] = ipi_count[id] - ipi_count_temp[id];
}


int ipi_test(int* p_seq)
{
    int ret;
    int core_id;


    for(core_id = 0; core_id < CPU_NUM; core_id++)
    {
        ret = bind_thread_to_cpu(ipi_t_id[core_id], p_seq[core_id]);
        if(ret)
        {
            printf("bind_thread_to_cpu fail!\n");
            return ret;
        }
    }
    get_ipi_test_count();


    ret = check_result();
    if(ret)
    {
        printf("check_result fail!\n");
        return ret;
    }


    return 0;
}


static void swap(int *p1,int *p2)
{
    int temp;


    temp = *p1;
    *p1 = *p2;
    *p2 = temp;
}
static void permutation(int* a,int index,int size)
{
    int id;
    int ret;


    //完成一种排列
    if(index == size)
    {
        ret = ipi_test(a);
        if(ret)
        {
            printf("ipi_test fail!\n");
            fail_flag = 1;
        }
    }
    else
    {
        for(id = index; id < size; id++)
        {
            swap(&a[id], &a[index]);
            permutation(a, index + 1, size);
            swap(&a[id], &a[index]);
        }
    }


}


int ipi_for_each_core_test(void)
{
    int id;
    int core_array[CPU_NUM];


    for(id = 0; id < CPU_NUM; id++)
        core_array[id] = id;


    permutation(core_array,0,CPU_NUM);


    return fail_flag;
}


static void *main_thread(void *arg)
{
    int ret;
    ret = permanent_thread_init();
    if(ret)
    {
        printf("child_thread_init fail!\n");
        goto fail;
    }
    ret = ipi_for_each_core_test();
    if(ret)
    {
        printf("get_normal_count fail!\n");
        goto fail;
    }
    ret = smp_cycling(ipi_t_id, NULL,CPU_NUM);
    if(ret)
    {
        printf("smp_cycling fail!\n");
        goto fail;
    }
    ret = pthread_mutex_destroy(&ipi_thread_mutex);
    if(ret)
    {
        printf("pthread_mutex_destroy fail!\n");
        goto fail;
    }


    *(int*)arg = 0;
    return arg;


fail:
    smp_cycling(ipi_t_id, NULL,CPU_NUM);
    pthread_mutex_destroy(&ipi_thread_mutex);
    *(int*)arg = ret;
    return arg;
}


#ifndef USE_CUNIT
 int main(void)
#else
 static int main_entry(void)
#endif
 {
    pthread_t main_pid;
    pthread_attr_t attr;
    int* p_main_ret = &ipi_main_ret;


    if(set_pthread_attr(&attr,MAIN_PROC_PRIORITY,SCHED_FIFO))
    {
        printf("set_pthread_attr fail!\n");
        return PTS_FAIL;
    }


    //创建主线程,绑到主核,优先级设置高于子线程
    if(pthread_create(&main_pid,&attr,main_thread,p_main_ret))
    {
        printf("create main thread fail!\n");
        return PTS_FAIL;
    }
    if(bind_thread_to_cpu(main_pid,MAIN_CORE_ID))
    {
        printf("bind_thread_to_cpu fail!\n");
        return PTS_FAIL;
    }


    if(pthread_join(main_pid,&p_main_ret))
    {
        printf("pthread_join main thread fail!\n");
        return PTS_FAIL;
    }


    if(*p_main_ret != 0)
    {
        printf("TEST FAIL\n");
        return PTS_FAIL;
    }


    printf("TEST PASSED\n");
    return PTS_PASS;
 }
#ifdef USE_CUNIT
 DEFINE_TC_ENTRY(smp_ipi_1_1, main_entry);
#endif

 其中,smp_test.h及smp_test_comm.c文件参见上一篇博客

https://blog.csdn.net/gaojy19881225/article/details/80527521

你可能感兴趣的:(线程)