comparison packages/kernel/current/tests/stress_threads.c @ 24:306eee292492 ecos-sw-1999-07-16

Merge from eCos master repository on 1999-07-16-05:47:06-BST
author jlarmour
date Fri, 16 Jul 1999 21:54:32 +0000
parents 53104bbd5f99
children 18ee5a9c102e
comparison
equal deleted inserted replaced
23:8883a9947b66 24:306eee292492
82 // STACK_SIZE is typical +2kB for printf family calls which use big 82 // STACK_SIZE is typical +2kB for printf family calls which use big
83 // auto variables. 83 // auto variables.
84 #define STACK_SIZE (2*1024 + CYGNUM_HAL_STACK_SIZE_TYPICAL) 84 #define STACK_SIZE (2*1024 + CYGNUM_HAL_STACK_SIZE_TYPICAL)
85 #define STACK_SIZE2 (8*1024 + CYGNUM_HAL_STACK_SIZE_TYPICAL) 85 #define STACK_SIZE2 (8*1024 + CYGNUM_HAL_STACK_SIZE_TYPICAL)
86 86
87 /* Allocate priorities in this order. This ensures that handlers 87 // The number of instances in each thread class
88 (which are the ones using the CPU) get enough CPU time to actually
89 complete their tasks. */
90 #define N_MAIN 1 88 #define N_MAIN 1
91 #define MAX_HANDLERS 19 89 #define MAX_HANDLERS 19
92 #define N_LISTENERS 4 90 #define N_LISTENERS 4
93 #define N_CLIENTS 4 91 #define N_CLIENTS 4
94 92 #define N_THREADS (N_MAIN+MAX_HANDLERS+N_LISTENERS+N_CLIENTS)
95 #if (CYGNUM_KERNEL_SCHED_PRIORITIES >= (N_MAIN+MAX_HANDLERS+N_LISTENERS+N_CLIENTS)) 93
94 /* Allocate priorities in this order. This ensures that handlers
95 (which are the ones using the CPU) get enough CPU time to actually
96 complete their tasks. */
97 //#define P_MAIN 0 // This is defined by libc
98 #define P_MAIN_PROGRAM 1
99 #define P_BASE_HANDLER 2
100 #define P_BASE_LISTENER (P_BASE_HANDLER+MAX_HANDLERS)
101 #define P_BASE_CLIENT (P_BASE_LISTENER+N_LISTENERS)
102 #define P_MAX (P_BASE_CLIENT+N_CLIENTS)
103
104
105 #if (CYGNUM_KERNEL_SCHED_PRIORITIES >= (P_MAX))
96 106
97 /* if we use the bitmap scheduler we must make sure we don't use the 107 /* if we use the bitmap scheduler we must make sure we don't use the
98 same priority more than once, so we must store those already in use */ 108 same priority more than once, so we must store those already in use */
99 static volatile char priority_in_use[N_MAIN+MAX_HANDLERS+N_LISTENERS+N_CLIENTS]; 109 static volatile char priority_in_use[P_MAX];
100 110
101 /* now declare (and allocate space for) some kernel objects, like the 111 /* now declare (and allocate space for) some kernel objects, like the
102 threads we will use */ 112 threads we will use */
103 cyg_thread main_thread_s; 113 cyg_thread main_thread_s;
104 cyg_thread handler_thread_s[MAX_HANDLERS]; 114 cyg_thread handler_thread_s[MAX_HANDLERS];
115 cyg_handle_t mainH; 125 cyg_handle_t mainH;
116 cyg_handle_t handlerH[MAX_HANDLERS]; 126 cyg_handle_t handlerH[MAX_HANDLERS];
117 cyg_handle_t listenerH[N_LISTENERS]; 127 cyg_handle_t listenerH[N_LISTENERS];
118 cyg_handle_t clientH[N_CLIENTS]; 128 cyg_handle_t clientH[N_CLIENTS];
119 129
130 /* space for thread names */
131 char thread_name[P_MAX][20];
132
120 /* and now variables for the procedure which is the thread */ 133 /* and now variables for the procedure which is the thread */
121 cyg_thread_entry_t main_program, client_program, listener_program, 134 cyg_thread_entry_t main_program, client_program, listener_program,
122 handler_program; 135 handler_program;
123 136
124 /* a few mutexes used in the code */ 137 /* a few mutexes used in the code */
135 /* a global variable with which the client and server coordinate */ 148 /* a global variable with which the client and server coordinate */
136 int client_makes_request = 0; 149 int client_makes_request = 0;
137 150
138 /* indicates that it's time to print out a report */ 151 /* indicates that it's time to print out a report */
139 int time_to_report = 0; 152 int time_to_report = 0;
140 /* print status after a delay of this many secs. */ 153 /* print status after a delay of this many secs. */
141 int time_report_delay; 154 int time_report_delay;
142 155
143 /*** now application-specific variables ***/ 156 /*** now application-specific variables ***/
144 /* an array that stores whether the handler threads are in use */ 157 /* an array that stores whether the handler threads are in use */
145 int handler_thread_in_use[MAX_HANDLERS]; 158 int handler_thread_in_use[MAX_HANDLERS];
168 char *name, /* optional thread name */ 181 char *name, /* optional thread name */
169 void *stack_base, /* stack base, NULL = alloc */ 182 void *stack_base, /* stack base, NULL = alloc */
170 cyg_ucount32 stack_size, /* stack size, 0 = default */ 183 cyg_ucount32 stack_size, /* stack size, 0 = default */
171 cyg_handle_t *handle, /* returned thread handle */ 184 cyg_handle_t *handle, /* returned thread handle */
172 cyg_thread *thread /* put thread here */ 185 cyg_thread *thread /* put thread here */
173 ); 186 );
174 187
175 int get_handler_slot(cyg_handle_t current_threadH); 188 int get_handler_slot(cyg_handle_t current_threadH);
176 void perform_stressful_tasks(void); 189 void perform_stressful_tasks(void);
177 void permute_array(char a[], int size, int seed); 190 void permute_array(char a[], int size, int seed);
178 void setup_death_alarm(cyg_addrword_t data, cyg_handle_t *deathHp, 191 void setup_death_alarm(cyg_addrword_t data, cyg_handle_t *deathHp,
189 202
190 /* main launches all the threads of the test */ 203 /* main launches all the threads of the test */
191 int 204 int
192 main(void) 205 main(void)
193 { 206 {
194 int i; 207 int i;
195 208
196 CYG_TEST_INIT(); 209 CYG_TEST_INIT();
197 CYG_TEST_INFO("# Entering stress's cyg_user_start() function"); 210 CYG_TEST_INFO("# Entering stress's cyg_user_start() function");
198 211
199 cyg_mutex_init(&client_request_lock); 212 cyg_mutex_init(&client_request_lock);
200 cyg_mutex_init(&statistics_print_lock); 213 cyg_mutex_init(&statistics_print_lock);
201 cyg_mutex_init(&free_handler_lock); 214 cyg_mutex_init(&free_handler_lock);
202 215
203 /* initialize statistics */ 216 /* initialize statistics */
204 memset(&statistics, 0, sizeof(statistics)); 217 memset(&statistics, 0, sizeof(statistics));
205 218
206 /* clear priority table */ 219 /* clear priority table */
207 for (i = 0; i < sizeof(priority_in_use); i++) 220 for (i = 0; i < sizeof(priority_in_use); i++)
208 priority_in_use[i] = 0; 221 priority_in_use[i] = 0;
209 222
210 /* initialize main thread */ 223 /* initialize main thread */
211 { 224 {
212 char thread_name[] = "main"; 225 sc_thread_create(P_MAIN_PROGRAM, main_program, (cyg_addrword_t) 0,
213 226 "main_program", (void *) main_stack, STACK_SIZE,
214 sc_thread_create(0, main_program, (cyg_addrword_t) 0, 227 &mainH, &main_thread_s);
215 thread_name, (void *) main_stack, STACK_SIZE, 228 priority_in_use[P_MAIN_PROGRAM]++;
216 &mainH, &main_thread_s); 229 }
217 priority_in_use[0]++; 230
218 } 231 /* initialize all handler threads to not be in use */
219 232 for (i = 0; i < MAX_HANDLERS; ++i) {
220 /* initialize all handler threads to not be in use */ 233 handler_thread_in_use[i] = 0;
221 for (i = 0; i < MAX_HANDLERS; ++i) { 234 }
222 handler_thread_in_use[i] = 0; 235 for (i = 0; i < N_LISTENERS; ++i) {
223 } 236 int prio = P_BASE_LISTENER + i;
224 for (i = 0; i < N_LISTENERS; ++i) { 237 char* name = &thread_name[prio][0];
225 int prio; 238 sprintf(name, "listener-%02d/%02d", i, prio);
226 char thread_name[20]; 239 sc_thread_create(prio, listener_program, (cyg_addrword_t) i,
227 sprintf(thread_name, "listener-%02d", i); 240 name, (void *) listener_stack[i], STACK_SIZE,
228 prio = N_MAIN + MAX_HANDLERS + i; 241 &listenerH[i], &listener_thread_s[i]);
229 sc_thread_create(prio, listener_program, (cyg_addrword_t) i, 242 CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!");
230 thread_name, (void *) listener_stack[i], STACK_SIZE, 243 priority_in_use[prio]++;
231 &listenerH[i], &listener_thread_s[i]); 244 }
232 CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!"); 245 for (i = 0; i < N_CLIENTS; ++i) {
233 priority_in_use[prio]++; 246 int prio = P_BASE_CLIENT + i;
234 } 247 char* name = &thread_name[prio][0];
235 for (i = 0; i < N_CLIENTS; ++i) { 248 sprintf(name, "client-%02d/%02d", i, prio);
236 int prio; 249 sc_thread_create(prio, client_program, (cyg_addrword_t) i,
237 char thread_name[20]; 250 name, (void *) client_stack[i], STACK_SIZE,
238 sprintf(thread_name, "client-%02d", i); 251 &(clientH[i]), &client_thread_s[i]);
239 prio = N_MAIN + MAX_HANDLERS + N_LISTENERS + i; 252 CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!");
240 sc_thread_create(prio, client_program, (cyg_addrword_t) i, 253 priority_in_use[prio]++;
241 thread_name, (void *) client_stack[i], STACK_SIZE, 254 }
242 &(clientH[i]), &client_thread_s[i]); 255
243 CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!"); 256 cyg_thread_resume(mainH);
244 priority_in_use[prio]++; 257 for (i = 0; i < N_CLIENTS; ++i) {
245 } 258 cyg_thread_resume(clientH[i]);
246 259 }
247 cyg_thread_resume(mainH); 260 for (i = 0; i < N_LISTENERS; ++i) {
248 for (i = 0; i < N_CLIENTS; ++i) { 261 cyg_thread_resume(listenerH[i]);
249 cyg_thread_resume(clientH[i]); 262 }
250 } 263
251 for (i = 0; i < N_LISTENERS; ++i) { 264 /* set up the alarm which gives periodic wakeups to say "time to
252 cyg_thread_resume(listenerH[i]); 265 print a report */
253 } 266 system_clockH = cyg_real_time_clock();
254 267 cyg_clock_to_counter(system_clockH, &counterH);
255 /* set up the alarm which gives periodic wakeups to say "time to 268
256 print a report */ 269 cyg_alarm_create(counterH, report_alarm_func,
257 system_clockH = cyg_real_time_clock(); 270 (cyg_addrword_t) 4000,
258 cyg_clock_to_counter(system_clockH, &counterH); 271 &report_alarmH, &report_alarm);
259 272 if (cyg_test_is_simulator) {
260 cyg_alarm_create(counterH, report_alarm_func, 273 time_report_delay = 2;
261 (cyg_addrword_t) 4000, 274 } else {
262 &report_alarmH, &report_alarm); 275 time_report_delay = 30;
263 if (cyg_test_is_simulator) { 276 }
264 time_report_delay = 2; 277
265 } else { 278 cyg_alarm_initialize(report_alarmH, cyg_current_time()+200,
266 time_report_delay = 30; 279 time_report_delay*100);
267 } 280
268 281 return 0;
269 cyg_alarm_initialize(report_alarmH, cyg_current_time()+200,
270 time_report_delay*100);
271 } 282 }
272 283
273 /* main_program() -- frees resources and prints status. */ 284 /* main_program() -- frees resources and prints status. */
274 void main_program(cyg_addrword_t data) 285 void main_program(cyg_addrword_t data)
275 { 286 {
338 } 349 }
339 350
340 /* client_program() -- an obnoxious client which makes a lot of requests */ 351 /* client_program() -- an obnoxious client which makes a lot of requests */
341 void client_program(cyg_addrword_t data) 352 void client_program(cyg_addrword_t data)
342 { 353 {
343 int delay; 354 int delay;
344 355
345 printf("# Starting client-%d\n", (int) data); 356 printf("# Starting client-%d\n", (int) data);
346 357
347 system_clockH = cyg_real_time_clock(); 358 system_clockH = cyg_real_time_clock();
348 cyg_clock_to_counter(system_clockH, &counterH); 359 cyg_clock_to_counter(system_clockH, &counterH);
349 360
350 for (;;) { 361 for (;;) {
351 delay = (rand() % 20); 362 delay = (rand() % 20);
352 363
353 /* now send a request to the server */ 364 /* now send a request to the server */
354 cyg_mutex_lock(&client_request_lock); { 365 cyg_mutex_lock(&client_request_lock); {
355 ++client_makes_request; 366 ++client_makes_request;
356 /* printf("client_makes_request %d\n", client_makes_request); */ 367 /* printf("client_makes_request %d\n", client_makes_request); */
357 } cyg_mutex_unlock(&client_request_lock); 368 } cyg_mutex_unlock(&client_request_lock);
358 369
359 cyg_thread_delay(10+delay); 370 cyg_thread_delay(10+delay);
360 /* cyg_thread_delay(0); */ 371 /* cyg_thread_delay(0); */
361 } 372 }
362 } 373 }
363 374
364 /* listener_program() -- listens for a request and spawns a handler to 375 /* listener_program() -- listens for a request and spawns a handler to
365 take care of the request */ 376 take care of the request */
366 void listener_program(cyg_addrword_t data) 377 void listener_program(cyg_addrword_t data)
379 } 390 }
380 } cyg_mutex_unlock(&client_request_lock); 391 } cyg_mutex_unlock(&client_request_lock);
381 392
382 if (make_request) { 393 if (make_request) {
383 int prio; 394 int prio;
395 char* name;
384 /* printf("just got a request from a client (count = %d)\n", */ 396 /* printf("just got a request from a client (count = %d)\n", */
385 /* client_makes_request); */ 397 /* client_makes_request); */
386 398
387 handler_slot = get_handler_slot(listenerH[(int) data]); 399 handler_slot = get_handler_slot(listenerH[(int) data]);
388 prio = N_MAIN+handler_slot; 400 prio = P_BASE_HANDLER+handler_slot;
401
402 name = &thread_name[prio][0];
403 sprintf(name, "handler-%02d/%02d", handler_slot, prio);
389 404
390 CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!"); 405 CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!");
391 priority_in_use[prio]++; 406 priority_in_use[prio]++;
392 sc_thread_create(prio, handler_program, 407 sc_thread_create(prio, handler_program,
393 (cyg_addrword_t) handler_slot, 408 (cyg_addrword_t) handler_slot,
394 "handler", (void *) handler_stack[handler_slot], 409 name, (void *) handler_stack[handler_slot],
395 STACK_SIZE2, &handlerH[handler_slot], 410 STACK_SIZE2, &handlerH[handler_slot],
396 &handler_thread_s[handler_slot]); 411 &handler_thread_s[handler_slot]);
397 cyg_thread_resume(handlerH[handler_slot]); 412 cyg_thread_resume(handlerH[handler_slot]);
398 ++statistics.handler_invocation_histogram[handler_slot]; 413 ++statistics.handler_invocation_histogram[handler_slot];
399 } 414 }
403 } 418 }
404 419
405 /* handler_program() -- is spawned to handle each incoming request */ 420 /* handler_program() -- is spawned to handle each incoming request */
406 void handler_program(cyg_addrword_t data) 421 void handler_program(cyg_addrword_t data)
407 { 422 {
408 /* here is where we perform specific stressful tasks */ 423 /* here is where we perform specific stressful tasks */
409 perform_stressful_tasks(); 424 perform_stressful_tasks();
410 425
411 cyg_thread_delay(4 + (int) (0.5*log(1.0 + fabs((rand() % 1000000))))); 426 cyg_thread_delay(4 + (int) (0.5*log(1.0 + fabs((rand() % 1000000)))));
412 /* cyg_thread_delay(0); */ 427 /* cyg_thread_delay(0); */
413 428
414 ++statistics.thread_exits; 429 ++statistics.thread_exits;
415 { 430 {
416 // Loop until the handler id and priority can be communicated to 431 // Loop until the handler id and priority can be communicated to
417 // the main_program. 432 // the main_program.
418 int freed = 0; 433 int freed = 0;
419 do { 434 do {
420 cyg_mutex_lock(&free_handler_lock); { 435 cyg_mutex_lock(&free_handler_lock); {
421 if (-1 == free_handler_id) { 436 if (-1 == free_handler_id) {
422 free_handler_id = data; 437 free_handler_id = data;
423 free_handler_pri = N_MAIN+(int) data; 438 free_handler_pri = P_BASE_HANDLER+(int) data;
424 freed = 1; 439 freed = 1;
425 } 440 }
426 } cyg_mutex_unlock(&free_handler_lock); 441 } cyg_mutex_unlock(&free_handler_lock);
427 if (!freed) 442 if (!freed)
428 cyg_thread_delay(2); 443 cyg_thread_delay(2);
429 } while (!freed); 444 } while (!freed);
430 } 445 }
431 446
432 // Then exit. 447 // Then exit.
433 cyg_thread_exit(); 448 cyg_thread_exit();
434 } 449 }
435 450
436 /* look for an available handler thread */ 451 /* look for an available handler thread */
437 int get_handler_slot(cyg_handle_t current_threadH) 452 int get_handler_slot(cyg_handle_t current_threadH)
438 { 453 {
461 /* do things which will stress the system */ 476 /* do things which will stress the system */
462 void perform_stressful_tasks() 477 void perform_stressful_tasks()
463 { 478 {
464 #define MAX_MALLOCED_SPACES 100 /* do this many mallocs at most */ 479 #define MAX_MALLOCED_SPACES 100 /* do this many mallocs at most */
465 #define MALLOCED_BASE_SIZE 1 /* basic size in bytes */ 480 #define MALLOCED_BASE_SIZE 1 /* basic size in bytes */
466 char *spaces[MAX_MALLOCED_SPACES]; 481 char *spaces[MAX_MALLOCED_SPACES];
467 unsigned int i; 482 unsigned int i;
468 483
469 cyg_mutex_t tmp_lock; 484 cyg_mutex_t tmp_lock;
470 485
471 cyg_uint8 pool_space[10][100]; 486 cyg_uint8 pool_space[10][100];
472 cyg_handle_t mempool_handles[10]; 487 cyg_handle_t mempool_handles[10];
473 cyg_mempool_fix mempool_objects[10]; 488 cyg_mempool_fix mempool_objects[10];
474 489
475 cyg_mutex_init(&tmp_lock); 490 cyg_mutex_init(&tmp_lock);
476 491
477 /* here I use malloc, which uses the kernel's variable memory pools. 492 /* here I use malloc, which uses the kernel's variable memory pools.
478 note that malloc/free is a bit simple-minded here: it does not 493 note that malloc/free is a bit simple-minded here: it does not
479 try to really fragment things, and it does not try to make the 494 try to really fragment things, and it does not try to make the
480 allocation/deallocation concurrent with other thread execution 495 allocation/deallocation concurrent with other thread execution
481 (although I'm about to throw in a yield()) */ 496 (although I'm about to throw in a yield()) */
482 for (i = 0; i < MAX_MALLOCED_SPACES; ++i) { 497 for (i = 0; i < MAX_MALLOCED_SPACES; ++i) {
483 ++statistics.malloc_tries; 498 ++statistics.malloc_tries;
484 /* spaces[i] = (char *) malloc(((int)(sqrt(i*2.0))+1)*MALLOCED_BASE_SIZE); */ 499 /* spaces[i] = (char *) malloc(((int)(sqrt(i*2.0))+1)*MALLOCED_BASE_SIZE); */
485 spaces[i] = (char *) malloc(((int)i*2.0+1)*MALLOCED_BASE_SIZE); 500 spaces[i] = (char *) malloc(((int)i*2.0+1)*MALLOCED_BASE_SIZE);
486 if (i % (MAX_MALLOCED_SPACES/10) == 0) { 501 if (i % (MAX_MALLOCED_SPACES/10) == 0) {
487 cyg_thread_yield(); 502 cyg_thread_yield();
488 } 503 }
489 if (i % (MAX_MALLOCED_SPACES/15) == 0) { 504 if (i % (MAX_MALLOCED_SPACES/15) == 0) {
490 cyg_thread_delay(i % 5); 505 cyg_thread_delay(i % 5);
491 } 506 }
492 } 507 }
493 508
494 /* now free it all up */ 509 /* now free it all up */
495 for (i = 0; i < MAX_MALLOCED_SPACES; ++i) { 510 for (i = 0; i < MAX_MALLOCED_SPACES; ++i) {
496 if (spaces[i] != NULL) { 511 if (spaces[i] != NULL) {
497 unsigned int j; 512 unsigned int j;
498 for (j = 0; j < (i*2+1)*MALLOCED_BASE_SIZE; ++j) { 513 for (j = 0; j < (i*2+1)*MALLOCED_BASE_SIZE; ++j) {
499 spaces[i][j] = 0xAA; /* write a bit pattern */ 514 spaces[i][j] = 0xAA; /* write a bit pattern */
500 } 515 }
501 free(spaces[i]); 516 free(spaces[i]);
502 } else { 517 } else {
503 ++statistics.malloc_failures; 518 ++statistics.malloc_failures;
504 } 519 }
505 } 520 }
506 /* now allocate and then free some fixed-size memory pools; for 521 /* now allocate and then free some fixed-size memory pools; for
507 now this is simple-minded because it does not have many threads 522 now this is simple-minded because it does not have many threads
508 sharing the memory pools and racing for memory. */ 523 sharing the memory pools and racing for memory. */
509 for (i = 0; i < 10; ++i) { 524 for (i = 0; i < 10; ++i) {
510 cyg_mempool_fix_create(pool_space[i], 100, (i+1)*3, 525 cyg_mempool_fix_create(pool_space[i], 100, (i+1)*3,
511 &mempool_handles[i], &mempool_objects[i]); 526 &mempool_handles[i], &mempool_objects[i]);
512 } 527 }
513 528
514 for (i = 0; i < 10; ++i) { 529 for (i = 0; i < 10; ++i) {
515 spaces[i] = cyg_mempool_fix_try_alloc(mempool_handles[i]); 530 spaces[i] = cyg_mempool_fix_try_alloc(mempool_handles[i]);
516 } 531 }
517 532
518 for (i = 0; i < 10; ++i) { 533 for (i = 0; i < 10; ++i) {
519 if (spaces[i]) { 534 if (spaces[i]) {
520 cyg_mempool_fix_delete(mempool_handles[i]); 535 cyg_mempool_fix_delete(mempool_handles[i]);
521 } 536 }
522 } 537 }
523 538
524 cyg_mutex_destroy(&tmp_lock); 539 cyg_mutex_destroy(&tmp_lock);
525 } 540 }
526 541
527 /* report_alarm_func() is invoked as an alarm handler, so it should be 542 /* report_alarm_func() is invoked as an alarm handler, so it should be
528 quick and simple. in this case it sets a global flag which is 543 quick and simple. in this case it sets a global flag which is
529 checked by main_program. */ 544 checked by main_program. */
536 /* this sets up death alarms. it gets the handle and alarm from the 551 /* this sets up death alarms. it gets the handle and alarm from the
537 caller, since they must persist for the life of the alarm */ 552 caller, since they must persist for the life of the alarm */
538 void setup_death_alarm(cyg_addrword_t data, cyg_handle_t *deathHp, 553 void setup_death_alarm(cyg_addrword_t data, cyg_handle_t *deathHp,
539 cyg_alarm *death_alarm_p, int *killed_p) 554 cyg_alarm *death_alarm_p, int *killed_p)
540 { 555 {
541 cyg_handle_t system_clockH, counterH; 556 cyg_handle_t system_clockH, counterH;
542 cyg_resolution_t rtc_res; 557 cyg_resolution_t rtc_res;
543 558
544 system_clockH = cyg_real_time_clock(); 559 system_clockH = cyg_real_time_clock();
545 cyg_clock_to_counter(system_clockH, &counterH); 560 cyg_clock_to_counter(system_clockH, &counterH);
546 561
547 cyg_alarm_create(counterH, death_alarm_func, 562 cyg_alarm_create(counterH, death_alarm_func,
548 (cyg_addrword_t) killed_p, 563 (cyg_addrword_t) killed_p,
549 deathHp, death_alarm_p); 564 deathHp, death_alarm_p);
550 rtc_res = cyg_clock_get_resolution(system_clockH); 565 rtc_res = cyg_clock_get_resolution(system_clockH);
551 { 566 {
552 cyg_tick_count_t tick_delay; 567 cyg_tick_count_t tick_delay;
553 tick_delay = (long long) 568 tick_delay = (long long)
554 ((1000000000.0*rtc_res.divisor) 569 ((1000000000.0*rtc_res.divisor)
555 *((double)DEATH_TIME_LIMIT)/((double)rtc_res.dividend)); 570 *((double)DEATH_TIME_LIMIT)/((double)rtc_res.dividend));
556 if ( cyg_test_is_simulator ) 571 if ( cyg_test_is_simulator )
557 tick_delay /= 10; 572 tick_delay /= 10;
558 #ifdef CYGPKG_HAL_I386_LINUX 573 #ifdef CYGPKG_HAL_I386_LINUX
559 // 20 seconds is a long time compared to the run time of other tests. 574 // 20 seconds is a long time compared to the run time of other tests.
560 // Reduce to 10 seconds, allowing more tests to get run. 575 // Reduce to 10 seconds, allowing more tests to get run.
561 tick_delay /= 2; 576 tick_delay /= 2;
562 #endif 577 #endif
563 578
564 cyg_alarm_initialize(*deathHp, cyg_current_time() + tick_delay, 0); 579 cyg_alarm_initialize(*deathHp, cyg_current_time() + tick_delay, 0);
565 } 580 }
566 } 581 }
567 #endif 582 #endif
568 583
569 /* death_alarm_func() is the alarm handler that kills the current 584 /* death_alarm_func() is the alarm handler that kills the current
570 thread after a specified timeout. It does so by setting a flag the 585 thread after a specified timeout. It does so by setting a flag the
571 thread is constantly checking. */ 586 thread is constantly checking. */
572 void death_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data) 587 void death_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data)
573 { 588 {
574 int *killed_p; 589 int *killed_p;
575 killed_p = (int *) data; 590 killed_p = (int *) data;
576 *killed_p = 1; 591 *killed_p = 1;
577 } 592 }
578 593
579 /* now I write the sc_ versions of the cyg_functions */ 594 /* now I write the sc_ versions of the cyg_functions */
580 void sc_thread_create( 595 void sc_thread_create(
581 cyg_addrword_t sched_info, /* scheduling info (eg pri) */ 596 cyg_addrword_t sched_info, /* scheduling info (eg pri) */
584 char *name, /* optional thread name */ 599 char *name, /* optional thread name */
585 void *stack_base, /* stack base, NULL = alloc */ 600 void *stack_base, /* stack base, NULL = alloc */
586 cyg_ucount32 stack_size, /* stack size, 0 = default */ 601 cyg_ucount32 stack_size, /* stack size, 0 = default */
587 cyg_handle_t *handle, /* returned thread handle */ 602 cyg_handle_t *handle, /* returned thread handle */
588 cyg_thread *thread /* put thread here */ 603 cyg_thread *thread /* put thread here */
589 ) 604 )
590 { 605 {
591 /*printf("Creating a thread -- priority is %lu\n", (unsigned long) sched_info);*/ 606 /*printf("Creating a thread -- priority is %lu\n", (unsigned long) sched_info);*/
592 /* fflush(stdout); */ 607 /* fflush(stdout); */
593 ++statistics.thread_creations; 608 ++statistics.thread_creations;
594 cyg_thread_create(sched_info, entry, entry_data, name, 609 cyg_thread_create(sched_info, entry, entry_data, name,
595 stack_base, stack_size, handle, thread); 610 stack_base, stack_size, handle, thread);
611
612 CYG_ASSERT(cyg_thread_get_priority(*handle) == (cyg_priority_t) sched_info,
613 "Didn't get requested priority!");
596 } 614 }
597 615
598 616
599 void print_statistics(int print_full) 617 void print_statistics(int print_full)
600 { 618 {
601 int i; 619 int i;
602 static int print_count = 0; 620 static int print_count = 0;
603 621
604 printf("State dump %d (time %02d.%02d.%02d)\n", 622 printf("State dump %d (time %02d.%02d.%02d)\n",
605 print_count, 623 print_count,
606 print_count*time_report_delay / (60*60), // hours 624 print_count*time_report_delay / (60*60), // hours
607 (print_count*time_report_delay / 60) % 60, // minutes 625 (print_count*time_report_delay / 60) % 60, // minutes
608 (print_count*time_report_delay ) % 60); // seconds 626 (print_count*time_report_delay ) % 60); // seconds
609 print_count++; 627 print_count++;
610 628
611 cyg_mutex_lock(&statistics_print_lock); { 629 cyg_mutex_lock(&statistics_print_lock); {
612 printf(" Handler-invocations: "); 630 printf(" Handler-invocations: ");
613 for (i = 0; i < MAX_HANDLERS; ++i) { 631 for (i = 0; i < MAX_HANDLERS; ++i) {
614 printf("%4lu ", statistics.handler_invocation_histogram[i]); 632 printf("%4lu ", statistics.handler_invocation_histogram[i]);
615 } 633 }
616 printf("\n"); 634 printf("\n");
617 printf(" malloc()-tries/failures: -- %7lu %7lu\n", 635 printf(" malloc()-tries/failures: -- %7lu %7lu\n",
618 statistics.malloc_tries, statistics.malloc_failures); 636 statistics.malloc_tries, statistics.malloc_failures);
619 printf(" client_makes_request: %d\n", client_makes_request); 637 printf(" client_makes_request: %d\n", client_makes_request);
620 } cyg_mutex_unlock(&statistics_print_lock); 638 } cyg_mutex_unlock(&statistics_print_lock);
621 639
622 // Add: Also occasionally dump individual threads' stack status. 640 // Add: Also occasionally dump individual threads' stack status.
623 if (0 == print_count % 5 || print_full) { 641 if (0 == print_count % 5 || print_full) {
624 cyg_test_dump_interrupt_stack_stats( " Status" ); 642 cyg_test_dump_interrupt_stack_stats( " Status" );
625 cyg_test_dump_idlethread_stack_stats( " Status" ); 643 cyg_test_dump_idlethread_stack_stats( " Status" );
626 } 644 }
627 } 645 }
628 646
629 #else /* (CYGNUM_KERNEL_SCHED_PRIORITIES >= */ 647 #else /* (CYGNUM_KERNEL_SCHED_PRIORITIES >= */
630 /* (N_MAIN+N_CLIENTS+N_LISTENERS+MAX_HANDLERS)) */ 648 /* (N_MAIN+N_CLIENTS+N_LISTENERS+MAX_HANDLERS)) */
631 #define N_A_MSG "not enough priorities available" 649 #define N_A_MSG "not enough priorities available"
632 #endif /* (CYGNUM_KERNEL_SCHED_PRIORITIES >= */ 650 #endif /* (CYGNUM_KERNEL_SCHED_PRIORITIES >= */
633 /* (N_MAIN+N_CLIENTS+N_LISTENERS+MAX_HANDLERS)) */ 651 /* (N_MAIN+N_CLIENTS+N_LISTENERS+MAX_HANDLERS)) */
634 652
635 #else /* CYGSEM_LIBC_MALLOC */ 653 #else /* CYGSEM_LIBC_MALLOC */
636 # define N_A_MSG "this test needs malloc" 654 # define N_A_MSG "this test needs malloc"
637 #endif /* CYGSEM_LIBC_MALLOC */ 655 #endif /* CYGSEM_LIBC_MALLOC */
638 656