⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stress_threads.c

📁 ecos为实时嵌入式操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
    }#endif /* DEATH_TIME_LIMIT */    if (client_makes_request > 0) {      int prio;      /*          printf("just got a request from a client (count = %d)\n", */      /*                 client_makes_request); */      cyg_mutex_lock(&client_request_lock); {        --client_makes_request;      } cyg_mutex_unlock(&client_request_lock);      handler_slot = get_handler_slot(listenerH[(int) data]);      prio = N_CLIENTS+N_LISTENERS+handler_slot;      priority_in_use[prio] = 1;      sc_thread_create(prio, handler_program,                       (cyg_addrword_t) handler_slot,                       "handler", (void *) handler_stack[handler_slot],                       STACK_SIZE2, &handlerH[handler_slot],                       &handler_thread_s[handler_slot]);      cyg_thread_resume(handlerH[handler_slot]);      ++statistics.handler_invocation_histogram[handler_slot];    }    cyg_thread_delay(1);  }}/* handler_program() -- is spawned to handle each incoming request */void handler_program(cyg_addrword_t data){  /* here is where we perform specific stressful tasks */  perform_stressful_tasks();  if (time_to_report) {    time_to_report = 0;    print_statistics();  }  cyg_thread_delay(4 + (int) (0.5*log(1.0 + fabs((rand() % 1000000)))));/*    cyg_thread_delay(0); */  /* lock the scheduler before we declare this thread slot available     and quit; note that cyg_thread_exit() will unlock the scheduler     as many times as necessary */  cyg_mutex_lock(&handler_slot_lock); {    handler_thread_in_use[data] = 0;    priority_in_use[N_CLIENTS + N_LISTENERS + (int) data] = 0;  } cyg_mutex_unlock(&handler_slot_lock);  /* FIXME: could there be a race condition right here? I unlock the     scheduler, so I could get pre-empted out, but meanwhile I have     declared this thread available again.  must fix it. */  sc_thread_exit();}/* look for an available handler thread */int get_handler_slot(cyg_handle_t current_threadH){  int i;  int found = 0;  while (!found) {    for (i = 0; i < MAX_HANDLERS; ++i) {      cyg_mutex_lock(&handler_slot_lock); {        if (!handler_thread_in_use[i]) {          found = 1;          handler_thread_in_use[i] = 1;        }      } cyg_mutex_unlock(&handler_slot_lock);      if (found) {        break;      }#ifdef DEATH_TIME_LIMIT      /* must do a check here to see if all clients have been killed,         since otherwise we might end up in an infinite loop */      if (n_clients_killed == N_CLIENTS) {	n_clients_killed = -1;    /* so we don't call this again */	CYG_TEST_PASS_FINISH("Kernel thread stress test OK");      }#endif    }    cyg_thread_delay(1);  }  return i;}/* do things which will stress the system */void perform_stressful_tasks(){#define MAX_MALLOCED_SPACES 100  /* do this many mallocs at most */#define MALLOCED_BASE_SIZE 1    /* basic size in bytes */  char *spaces[MAX_MALLOCED_SPACES];  unsigned int i;  cyg_mutex_t tmp_lock;  cyg_uint8 pool_space[10][100];  cyg_handle_t mempool_handles[10];  cyg_mempool_fix mempool_objects[10];  cyg_mutex_init(&tmp_lock);  /* here I use malloc, which uses the kernel's variable memory pools.     note that malloc/free is a bit simple-minded here: it does not     try to really fragment things, and it does not try to make the     allocation/deallocation concurrent with other thread execution     (although I'm about to throw in a yield()) */  for (i = 0; i < MAX_MALLOCED_SPACES; ++i) {    ++statistics.malloc_tries;/*      spaces[i] = (char *) malloc(((int)(sqrt(i*2.0))+1)*MALLOCED_BASE_SIZE); */    spaces[i] = (char *) malloc(((int)i*2.0+1)*MALLOCED_BASE_SIZE);    if (i % 100 == 0) {      cyg_thread_yield();    }  }  /* now free it all up */  for (i = 0; i < MAX_MALLOCED_SPACES; ++i) {    if (spaces[i] != NULL) {      unsigned int j;      for (j = 0; j < (i*2+1)*MALLOCED_BASE_SIZE; ++j) {	spaces[i][j] = 0xAA;	/* write a bit pattern */      }      free(spaces[i]);    } else {      ++statistics.malloc_failures;    }  }  /* now allocate and then free some fixed-size memory pools; for     now this is simple-minded because it does not have many threads     sharing the memory pools and racing for memory. */  for (i = 0; i < 10; ++i) {    cyg_mempool_fix_create(pool_space[i], 100, (i+1)*3,                           &mempool_handles[i], &mempool_objects[i]);  }  for (i = 0; i < 10; ++i) {    spaces[i] = cyg_mempool_fix_try_alloc(mempool_handles[i]);  }  for (i = 0; i < 10; ++i) {    if (spaces[i]) {      cyg_mempool_fix_delete(mempool_handles[i]);    }  }  cyg_mutex_destroy(&tmp_lock);}/* report_alarm_func() is invoked as an alarm handler, so it should be   quick and simple.  in this case it sets a global flag which is   checked by threads. */void report_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data){    time_to_report = 1;}/* this sets up death alarms. it gets the handle and alarm from the   caller, since they must persist for the life of the alarm */void setup_death_alarm(cyg_addrword_t data, cyg_handle_t *deathHp,                       cyg_alarm *death_alarm_p, int *killed_p){#ifdef DEATH_TIME_LIMIT  cyg_handle_t system_clockH, counterH;  cyg_resolution_t rtc_res;  system_clockH = cyg_real_time_clock();  cyg_clock_to_counter(system_clockH, &counterH);  cyg_alarm_create(counterH, death_alarm_func,                   (cyg_addrword_t) killed_p,                   deathHp, death_alarm_p);  rtc_res = cyg_clock_get_resolution(system_clockH);  {    cyg_tick_count_t tick_delay;    tick_delay = (long long)      ((1000000000.0*rtc_res.divisor)       *((double)DEATH_TIME_LIMIT)/((double)rtc_res.dividend));    if ( cyg_test_is_simulator )        tick_delay /= 10;    cyg_alarm_initialize(*deathHp, cyg_current_time() + tick_delay, 0);  }#endif /* DEATH_TIME_LIMIT */}/* death_alarm_func() is the alarm handler that kills the current   thread after a specified timeout. It does so by setting a flag the   thread is constantly checking. */void death_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data){  int *killed_p;  killed_p = (int *) data;  *killed_p = 1;}#ifdef DEATH_TIME_LIMIT/* handle_death is called by a client thread when it dies; it kills   off the alarm */void handle_death(cyg_handle_t deathH, cyg_handle_t alarmH){  ++n_clients_killed;  cyg_alarm_delete(deathH);  cyg_alarm_delete(alarmH);  cyg_thread_exit();}#endif /* DEATH_TIME_LIMIT *//* now I write the sc_ versions of the cyg_functions */void sc_thread_create(    cyg_addrword_t        sched_info,          /* scheduling info (eg pri)  */    cyg_thread_entry_t  *entry,                /* entry point function      */    cyg_addrword_t        entry_data,          /* entry data                */    char                *name,                 /* optional thread name      */    void                *stack_base,           /* stack base, NULL = alloc  */    cyg_ucount32        stack_size,            /* stack size, 0 = default   */    cyg_handle_t        *handle,               /* returned thread handle    */    cyg_thread          *thread                /* put thread here           */){/*printf("Creating a thread -- priority is %lu\n", (unsigned long) sched_info);*//*    fflush(stdout); */  ++statistics.thread_creations;  cyg_thread_create(sched_info, entry, entry_data, name,                    stack_base, stack_size, handle, thread);}void sc_thread_exit(){/*    printf("exiting\n"); *//*    fflush(stdout); */  ++statistics.thread_exits;  cyg_thread_exit();}void print_statistics(void){  int i;  cyg_mutex_lock(&statistics_print_lock); {    printf("Handler-invocations: ");    for (i = 0; i < MAX_HANDLERS; ++i) {      printf("%4lu ", statistics.handler_invocation_histogram[i]);    }    printf("\n");    printf("malloc()-tries/failures: -- %7lu %7lu\n",           statistics.malloc_tries, statistics.malloc_failures);    printf("client_makes_request:       %d\n", client_makes_request);  } cyg_mutex_unlock(&statistics_print_lock);}#else /* CYGSEM_LIBC_MALLOC */# define N_A_MSG "this test needs malloc"#endif /* CYGSEM_LIBC_MALLOC */#else /* CYGFUN_KERNEL_THREADS_TIMER */# define N_A_MSG "this test needs kernel threads timer"#endif /* CYGFUN_KERNEL_THREADS_TIMER */#else /* CYGPKG_LIBM */# define N_A_MSG "this test needs libm"#endif /* CYGPKG_LIBM */#else /* CYGSEM_LIBC_STDIO */# define N_A_MSG "this test needs stdio"#endif /* CYGSEM_LIBC_STDIO */#else // def CYGFUN_KERNEL_API_C# define N_A_MSG "this test needs Kernel C API"#endif#else // def CYGPKG_KERNEL && CYGPKG_IO && CYGPKG_LIBC# define N_A_MSG "this tests needs Kernel, libc and IO"#endif#ifdef N_A_MSGexternC voidcyg_start( void ){    CYG_TEST_INIT();    CYG_TEST_NA( N_A_MSG);}#endif // N_A_MSG

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -