核间中断测试
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