00001
00002
00003 #include "copyright.h"
00004
00005
00006 #ifdef __i386__
00007 #define assert(ex) \
00008 do { \
00009 if (!(ex)) { \
00010 fprintf (stderr, "[%s:%d] Assertion " #ex " failed\n", __FILE__, __LINE__); \
00011 abort(); \
00012 } \
00013 } while (0)
00014 #else
00015 #include <assert.h>
00016 #endif
00017
00018
00019
00020
00021
00022
00023
00024
00025 typedef unsigned long iaddr_t;
00026
00027 #include <stdarg.h>
00028 #include <stdio.h>
00029 #include "b.h"
00030 #include "qt.h"
00031 #include "stp.h"
00032
00033 extern void exit (int status);
00034 extern int atoi (char const *s);
00035 extern int fprintf (FILE *out, char const *fmt, ...);
00036 extern int fputs (char const *s, FILE *fp);
00037 extern void free (void *sto);
00038 extern void *malloc (unsigned nbytes);
00039 extern void perror (char const *s);
00040
00041 void usage (void);
00042 void tracer(void);
00043
00044
00045 #define ROUND(v, a) (((v) + (a) - 1) & ~((a)-1))
00046
00047 typedef struct thread_t {
00048 qt_t *qt;
00049 void *stk;
00050 void *top;
00051 struct thread_t *next;
00052 } thread_t;
00053
00054
00055 static thread_t *
00056 t_alloc (void)
00057 {
00058 thread_t *t;
00059 int ssz = 0x1000;
00060
00061 t = malloc (sizeof(thread_t));
00062 if (!t) {
00063 perror ("malloc");
00064 exit (1);
00065 }
00066 assert (ssz > QT_STKBASE);
00067 t->stk = malloc (ssz);
00068 t->stk = (void *)ROUND (((iaddr_t)t->stk), QT_STKALIGN);
00069 if (!t->stk) {
00070 perror ("malloc");
00071 exit (1);
00072 }
00073 assert ((((iaddr_t)t->stk) & (QT_STKALIGN-1)) == 0);
00074 t->top = QT_SP (t->stk, ssz - QT_STKBASE);
00075
00076 return (t);
00077 }
00078
00079
00080 static thread_t *
00081 t_create (qt_only_t *starter, void *p0, qt_userf_t *f)
00082 {
00083 thread_t *t;
00084
00085 t = t_alloc();
00086 t->qt = QT_ARGS (t->top, p0, t, f, starter);
00087 return (t);
00088 }
00089
00090
00091 static void
00092 t_free (thread_t *t)
00093 {
00094 free (t->stk);
00095 free (t);
00096 }
00097
00098
00099 static void *
00100 t_null (qt_t *old, void *p1, void *p2)
00101 {
00102
00103 }
00104
00105
00106 static void *
00107 t_splat (qt_t *old, void *oldp, void *null)
00108 {
00109 *(qt_t **)oldp = old;
00110
00111 }
00112
00113
00114 static char const test01_msg[] =
00115 "*QT_SP(sto,sz), QT_ARGS(top,p0,p1,userf,first)";
00116
00117 static char const *test01_descr[] = {
00118 "Performs 1 QT_SP and one QT_ARGS per iteration.",
00119 NULL
00120 };
00121
00122
00123
00124
00125 static void
00126 test01 (int n)
00127 {
00128 char stack[QT_STKBASE+QT_STKALIGN];
00129 char *stk;
00130 qt_t *top;
00131
00132 stk = (char *)ROUND (((iaddr_t)stack), QT_STKALIGN);
00133
00134 {
00135 int i;
00136
00137 for (i=0; i<QT_STKBASE; ++i) {
00138 stk[i] = 0;
00139 }
00140 }
00141
00142 while (n>0) {
00143
00144 top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
00145 #ifdef NDEF
00146 top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
00147 top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
00148 top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
00149 top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
00150
00151 top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
00152 top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
00153 top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
00154 top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
00155 top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
00156
00157 n -= 10;
00158 #else
00159 n -= 1;
00160 #endif
00161 }
00162 }
00163
00164
00165 static char const test02_msg[] = "QT_BLOCKI (0, 0, test02_aux, t->qt)";
00166 static qt_t *rootthread;
00167
00168 static void
00169 test02_aux1 (void *pu, void *pt, qt_userf_t *f)
00170 {
00171 QT_ABORT (t_null, 0, 0, rootthread);
00172 }
00173
00174 static void *
00175 test02_aux2 (qt_t *old, void *farg1, void *farg2)
00176 {
00177 rootthread = old;
00178
00179 }
00180
00181 static void
00182 test02 (int n)
00183 {
00184 thread_t *t;
00185
00186 while (n>0) {
00187 t = t_create (test02_aux1, 0, 0);
00188 QT_BLOCKI (test02_aux2, 0, 0, t->qt);
00189 t_free (t);
00190 t = t_create (test02_aux1, 0, 0);
00191 QT_BLOCKI (test02_aux2, 0, 0, t->qt);
00192 t_free (t);
00193 t = t_create (test02_aux1, 0, 0);
00194 QT_BLOCKI (test02_aux2, 0, 0, t->qt);
00195 t_free (t);
00196 t = t_create (test02_aux1, 0, 0);
00197 QT_BLOCKI (test02_aux2, 0, 0, t->qt);
00198 t_free (t);
00199 t = t_create (test02_aux1, 0, 0);
00200 QT_BLOCKI (test02_aux2, 0, 0, t->qt);
00201 t_free (t);
00202
00203 n -= 5;
00204 }
00205 }
00206
00207
00208 static char const test03_msg[] = "QT_BLOCKI (...) test vals are right.";
00209
00210
00211
00212
00213
00214 static void *
00215 test03_aux0 (qt_t *old_is_garbage, void *farg1, void *farg2)
00216 {
00217 assert (farg1 == (void *)5);
00218 assert (farg2 == (void *)6);
00219 return ((void *)15);
00220 }
00221
00222
00223
00224
00225
00226 static void *
00227 test03_aux1 (qt_t *old, void *farg1, void *farg2)
00228 {
00229 assert (old != NULL);
00230 assert (farg1 == (void *)5);
00231 assert (farg2 == (void *)6);
00232 rootthread = old;
00233 return ((void *)16);
00234 }
00235
00236 static void
00237 test03_aux2 (void *pu, void *pt, qt_userf_t *f)
00238 {
00239 assert (pu == (void *)1);
00240 assert (f == (qt_userf_t *)4);
00241 QT_ABORT (test03_aux0, (void *)5, (void *)6, rootthread);
00242 }
00243
00244 static void
00245 test03 (int n)
00246 {
00247 thread_t *t;
00248 void *rv;
00249
00250 while (n>0) {
00251 t = t_create (test03_aux2, (void *)1, (qt_userf_t *)4);
00252 rv = QT_BLOCKI (test03_aux1, (void *)5, (void *)6, t->qt);
00253 assert (rv == (void *)15);
00254 t_free (t);
00255
00256 --n;
00257 }
00258 }
00259
00260
00261 static char const test04_msg[] = "stp_start w/ no threads.";
00262
00263 static void
00264 test04 (int n)
00265 {
00266 while (n>0) {
00267 stp_init(); stp_start();
00268 stp_init(); stp_start();
00269 stp_init(); stp_start();
00270 stp_init(); stp_start();
00271 stp_init(); stp_start();
00272
00273 stp_init(); stp_start();
00274 stp_init(); stp_start();
00275 stp_init(); stp_start();
00276 stp_init(); stp_start();
00277 stp_init(); stp_start();
00278
00279 n -= 10;
00280 }
00281 }
00282
00283
00284 static char const test05_msg[] = "stp w/ 2 yielding thread.";
00285
00286 static void
00287 test05_aux (void *null)
00288 {
00289 stp_yield();
00290 stp_yield();
00291 }
00292
00293 static void
00294 test05 (int n)
00295 {
00296 while (n>0) {
00297 stp_init();
00298 stp_create (test05_aux, 0);
00299 stp_create (test05_aux, 0);
00300 stp_start();
00301
00302 --n;
00303 }
00304 }
00305
00306
00307 static char const test06_msg[] = "*QT_ARGS(...), QT_BLOCKI one thread";
00308
00309 static char const *test06_descr[] = {
00310 "Does a QT_ARGS, QT_BLOCKI to a helper function that saves the",
00311 "stack pointer of the main thread, calls an `only' function that",
00312 "saves aborts the thread, calling a null helper function.",
00313 ":: start/stop = QT_ARGS + QT_BLOCKI + QT_ABORT + 3 procedure calls.",
00314 NULL
00315 };
00316
00317
00318
00319
00320
00321 static qt_t *test06_sp;
00322
00323
00324 static void
00325 test06_aux2 (void *null0a, void *null1b, void *null2b, qt_userf_t *null)
00326 {
00327 QT_ABORT (t_null, 0, 0, test06_sp);
00328 }
00329
00330
00331 static void *
00332 test06_aux3 (qt_t *sp, void *null0c, void *null1c)
00333 {
00334 test06_sp = sp;
00335
00336 }
00337
00338
00339 static void
00340 test06 (int n)
00341 {
00342 thread_t *t;
00343
00344 t = t_create (0, 0, 0);
00345
00346 while (n>0) {
00347
00348 QT_ARGS (t->top, 0, 0, 0, test06_aux2);
00349 QT_BLOCKI (test06_aux3, 0, 0, t->qt);
00350 #ifdef NDEF
00351
00352 QT_ARGS (t->top, 0, 0, 0, test06_aux2);
00353 QT_BLOCKI (test06_aux3, 0, 0, t->qt);
00354
00355
00356 QT_ARGS (t->top, 0, 0, 0, test06_aux2);
00357 QT_BLOCKI (test06_aux3, 0, 0, t->qt);
00358
00359
00360 QT_ARGS (t->top, 0, 0, 0, test06_aux2);
00361 QT_BLOCKI (test06_aux3, 0, 0, t->qt);
00362
00363
00364 QT_ARGS (t->top, 0, 0, 0, test06_aux2);
00365 QT_BLOCKI (test06_aux3, 0, 0, t->qt);
00366
00367 n -= 5;
00368 #else
00369 --n;
00370 #endif
00371 }
00372 }
00373
00374 static char test07_msg[] = "*cswap between threads";
00375
00376 static char const *test07_descr[] = {
00377 "Build a chain of threads where each thread has a fixed successor.",
00378 "There is no scheduling performed. Each thread but one is a loop",
00379 "that simply blocks with QT_BLOCKI, calling a helper that saves the",
00380 "current stack pointer. The last thread decrements a count, and,",
00381 "if zero, aborts back to the main thread. Else it continues with",
00382 "the blocking chain. The count is divided by the number of threads",
00383 "in the chain, so `n' is the number of integer block operations.",
00384 ":: integer cswap = QT_BLOCKI + a procedure call.",
00385 NULL
00386 };
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 static qt_t *test07_heavy;
00402
00403 #define TEST07_N (4)
00404
00405
00406 static void
00407 test07_aux2 (void *null0, void *mep, void *nxtp, qt_userf_t *null)
00408 {
00409 qt_t *nxt;
00410
00411 while (1) {
00412 nxt = *(qt_t **)nxtp;
00413 #ifdef NDEF
00414 printf ("Helper 0x%p\n", nxtp);
00415 #endif
00416 QT_BLOCKI (t_splat, mep, 0, nxt);
00417 }
00418 }
00419
00420 static void
00421 test07_aux3 (void *np, void *mep, void *nxtp, qt_userf_t *null)
00422 {
00423 int n;
00424
00425 n = *(int *)np;
00426 while (1) {
00427 n -= TEST07_N;
00428 if (n<0) {
00429 QT_ABORT (t_splat, mep, 0, test07_heavy);
00430 }
00431 QT_BLOCKI (t_splat, mep, 0, *(qt_t **)nxtp);
00432 }
00433 }
00434
00435
00436 static void
00437 test07 (int n)
00438 {
00439 int i;
00440 thread_t *t[TEST07_N];
00441
00442 for (i=0; i<TEST07_N; ++i) {
00443 t[i] = t_create (0, 0, 0);
00444 }
00445 for (i=0; i<TEST07_N-1; ++i) {
00446
00447 QT_ARGS (t[i]->top, 0, &t[i]->qt, &t[i+1]->qt, test07_aux2);
00448 }
00449
00450 QT_ARGS (t[i]->top, &n, &t[TEST07_N-1]->qt, &t[0]->qt, test07_aux3);
00451 QT_BLOCKI (t_splat, &test07_heavy, 0, t[0]->qt);
00452 }
00453
00454
00455 static char test08_msg[] = "Floating-point cswap between threads";
00456
00457 static char const *test08_descr[] = {
00458 "Measure context switch times including floating-point, use QT_BLOCK.",
00459 NULL
00460 };
00461
00462 static qt_t *test08_heavy;
00463
00464 #define TEST08_N (4)
00465
00466
00467 static void
00468 test08_aux2 (void *null0, void *mep, void *nxtp, qt_userf_t *null)
00469 {
00470 qt_t *nxt;
00471
00472 while (1) {
00473 nxt = *(qt_t **)nxtp;
00474 QT_BLOCK (t_splat, mep, 0, nxt);
00475 }
00476 }
00477
00478 static void
00479 test08_aux3 (void *np, void *mep, void *nxtp, qt_userf_t *null)
00480 {
00481 int n;
00482
00483 n = *(int *)np;
00484 while (1) {
00485 n -= TEST08_N;
00486 if (n<0) {
00487 QT_ABORT (t_splat, mep, 0, test08_heavy);
00488 }
00489 QT_BLOCK (t_splat, mep, 0, *(qt_t **)nxtp);
00490 }
00491 }
00492
00493
00494 static void
00495 test08 (int n)
00496 {
00497 int i;
00498 thread_t *t[TEST08_N];
00499
00500 for (i=0; i<TEST08_N; ++i) {
00501 t[i] = t_create (0, 0, 0);
00502 }
00503 for (i=0; i<TEST08_N-1; ++i) {
00504
00505 QT_ARGS (t[i]->top, 0, &t[i]->qt, &t[i+1]->qt, test08_aux2);
00506 }
00507
00508 QT_ARGS (t[i]->top, &n, &t[TEST08_N-1]->qt, &t[0]->qt, test08_aux3);
00509 QT_BLOCK (t_splat, &test08_heavy, 0, t[0]->qt);
00510 }
00511
00512
00513
00514
00515 char const test09_msg[] = { "Start and run threads using varargs." };
00516
00517 thread_t *test09_t0, *test09_t1, *test09_t2, *test09_main;
00518
00519 thread_t *
00520 test09_create (qt_startup_t *start, qt_vuserf_t *f,
00521 qt_cleanup_t *cleanup, int nbytes, ...)
00522 {
00523 va_list ap;
00524 thread_t *t;
00525
00526 t = t_alloc();
00527 va_start (ap, nbytes);
00528 t->qt = QT_VARGS (t->top, nbytes, ap, t, start, f, cleanup);
00529 va_end (ap);
00530 return (t);
00531 }
00532
00533
00534 static void
00535 test09_cleanup (void *pt, void *vuserf_retval)
00536 {
00537 assert (vuserf_retval == (void *)17);
00538 QT_ABORT (t_splat, &((thread_t *)pt)->qt, 0,
00539 ((thread_t *)pt)->next->qt);
00540 }
00541
00542
00543 static void
00544 test09_start (void *pt)
00545 {
00546 }
00547
00548
00549 static void *
00550 test09_user0 (void)
00551 {
00552 QT_BLOCKI (t_splat, &test09_t0->qt, 0, test09_t1->qt);
00553 return ((void *)17);
00554 }
00555
00556 static void *
00557 test09_user2 (int one, int two)
00558 {
00559 assert (one == 1);
00560 assert (two == 2);
00561 QT_BLOCKI (t_splat, &test09_t1->qt, 0, test09_t2->qt);
00562 assert (one == 1);
00563 assert (two == 2);
00564 return ((void *)17);
00565 }
00566
00567 static void *
00568 test09_user10 (int one, int two, int three, int four, int five,
00569 int six, int seven, int eight, int nine, int ten)
00570 {
00571 assert (one == 1);
00572 assert (two == 2);
00573 assert (three == 3);
00574 assert (four == 4);
00575 assert (five == 5);
00576 assert (six == 6);
00577 assert (seven == 7);
00578 assert (eight == 8);
00579 assert (nine == 9);
00580 assert (ten == 10);
00581 QT_BLOCKI (t_splat, &test09_t2->qt, 0, test09_main->qt);
00582 assert (one == 1);
00583 assert (two == 2);
00584 assert (three == 3);
00585 assert (four == 4);
00586 assert (five == 5);
00587 assert (six == 6);
00588 assert (seven == 7);
00589 assert (eight == 8);
00590 assert (nine == 9);
00591 assert (ten == 10);
00592 return ((void *)17);
00593 }
00594
00595
00596 void
00597 test09 (int n)
00598 {
00599 thread_t main;
00600
00601 test09_main = &main;
00602
00603 while (--n >= 0) {
00604 test09_t0 = test09_create (test09_start, (qt_vuserf_t*)test09_user0,
00605 test09_cleanup, 0);
00606 test09_t1 = test09_create (test09_start, (qt_vuserf_t*)test09_user2,
00607 test09_cleanup, 2 * sizeof(qt_word_t), 1, 2);
00608 test09_t2 = test09_create (test09_start, (qt_vuserf_t*)test09_user10,
00609 test09_cleanup, 10 * sizeof(qt_word_t),
00610 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
00611
00612
00613 test09_t0->next = test09_t1;
00614 test09_t1->next = test09_t2;
00615 test09_t2->next = test09_main;
00616
00617 QT_BLOCKI (t_splat, &test09_main->qt, 0, test09_t0->qt);
00618 QT_BLOCKI (t_splat, &test09_main->qt, 0, test09_t0->qt);
00619
00620 t_free (test09_t0);
00621 t_free (test09_t1);
00622 t_free (test09_t2);
00623 }
00624 }
00625
00626
00627
00628
00629 char const test10_msg[] = { "*Test varargs init & startup w/ 0 args." };
00630
00631 char const *test10_descr[] = {
00632 "Start and stop threads that use variant argument lists (varargs).",
00633 "Each thread is initialized by calling a routine that calls",
00634 "QT_VARARGS. Then runs the thread by calling QT_BLOCKI to hald the",
00635 "main thread, a helper that saves the main thread's stack pointer,",
00636 "a null startup function, a null user function, a cleanup function",
00637 "that calls QT_ABORT and restarts the main thread. Copies no user",
00638 "parameters.",
00639 ":: varargs start/stop = QT_BLOCKI + QT_ABORT + 6 function calls.",
00640 NULL
00641 };
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653 static void
00654 test10_startup (void *pt)
00655 {
00656 }
00657
00658
00659
00660
00661 static void *
00662 test10_run (int arg0, ...)
00663 {
00664
00665 }
00666
00667
00668
00669
00670
00671
00672 void
00673 test10_cleanup (void *pt, void *vuserf_retval)
00674 {
00675 QT_ABORT (t_null, 0, 0, ((thread_t *)pt)->qt);
00676 }
00677
00678
00679 void
00680 test10_init (thread_t *new, thread_t *next, int nbytes, ...)
00681 {
00682 va_list ap;
00683
00684 va_start (ap, nbytes);
00685 new->qt = QT_VARGS (new->top, nbytes, ap, next, test10_startup,
00686 test10_run, test10_cleanup);
00687 va_end (ap);
00688 }
00689
00690
00691 void
00692 test10 (int n)
00693 {
00694 thread_t main;
00695 thread_t *t;
00696
00697 t = t_alloc();
00698 t->next = &main;
00699
00700 while (--n >= 0) {
00701 test10_init (t, &main, 0);
00702 QT_BLOCKI (t_splat, &main.qt, 0, t->qt);
00703 }
00704 t_free (t);
00705 }
00706
00707
00708 char const test11_msg[] = { "*Test varargs init & startup w/ 2 args." };
00709
00710 char const *test11_descr[] = {
00711 "Varargs initialization/run. Copies 2 user arguments.",
00712 ":: varargs 2 start/stop = QT_VARGS(2 args), QT_BLOCKI, QT_ABORT, 6 f() calls.",
00713 NULL
00714 };
00715
00716
00717 void
00718 test11 (int n)
00719 {
00720 thread_t main;
00721 thread_t *t;
00722
00723 t = t_alloc();
00724 t->next = &main;
00725
00726 while (--n >= 0) {
00727 test10_init (t, &main, 2 * sizeof(int), 2, 1);
00728 QT_BLOCKI (t_splat, &main.qt, 0, t->qt);
00729 }
00730 t_free (t);
00731 }
00732
00733 char const test12_msg[] = { "*Test varargs init & startup w/ 4 args." };
00734
00735 char const *test12_descr[] = {
00736 "Varargs initialization/run. Copies 4 user arguments.",
00737 ":: varargs 4 start/stop = QT_VARGS(4 args), QT_BLOCKI, QT_ABORT, 6 f() calls.",
00738 NULL
00739 };
00740
00741
00742 void
00743 test12 (int n)
00744 {
00745 thread_t main;
00746 thread_t *t;
00747
00748 t = t_alloc();
00749 t->next = &main;
00750
00751 while (--n >= 0) {
00752 test10_init (t, &main, 4 * sizeof(int), 4, 3, 2, 1);
00753 QT_BLOCKI (t_splat, &main.qt, 0, t->qt);
00754 }
00755 t_free (t);
00756 }
00757
00758
00759 char const test13_msg[] = { "*Test varargs init & startup w/ 8 args." };
00760
00761 char const *test13_descr[] = {
00762 "Varargs initialization/run. Copies 8 user arguments.",
00763 ":: varargs 8 start/stop = QT_VARGS(8 args), QT_BLOCKI, QT_ABORT, 6 f() calls.",
00764 NULL
00765 };
00766
00767 void
00768 test13 (int n)
00769 {
00770 thread_t main;
00771 thread_t *t;
00772
00773 t = t_alloc();
00774 t->next = &main;
00775
00776 while (--n >= 0) {
00777 test10_init (t, &main, 8 * sizeof(int), 8, 7, 6, 5, 4, 3, 2, 1);
00778 QT_BLOCKI (t_splat, &main.qt, 0, t->qt);
00779 }
00780 t_free (t);
00781 }
00782
00783
00784 char const test14_msg[] = { "*Test varargs initialization w/ 0 args." };
00785
00786 char const *test14_descr[] = {
00787 "Varargs initialization without running the thread. Just calls",
00788 "QT_VARGS.",
00789 ":: varargs 0 init = QT_VARGS()",
00790 NULL
00791 };
00792
00793 void
00794 test14 (int n)
00795 {
00796 thread_t main;
00797 thread_t *t;
00798
00799 t = t_alloc();
00800 t->next = &main;
00801
00802 while (--n >= 0) {
00803 test10_init (t, &main, 0 * sizeof(int));
00804 }
00805 t_free (t);
00806 }
00807
00808
00809 char const test15_msg[] = { "*Test varargs initialization w/ 2 args." };
00810
00811 char const *test15_descr[] = {
00812 "Varargs initialization without running the thread. Just calls",
00813 "QT_VARGS.",
00814 ":: varargs 2 init = QT_VARGS(2 args)",
00815 NULL
00816 };
00817
00818 void
00819 test15 (int n)
00820 {
00821 thread_t main;
00822 thread_t *t;
00823
00824 t = t_alloc();
00825 t->next = &main;
00826
00827 while (--n >= 0) {
00828 test10_init (t, &main, 2 * sizeof(int), 2, 1);
00829 }
00830 t_free (t);
00831 }
00832
00833 char const test16_msg[] = { "*Test varargs initialization w/ 4 args." };
00834
00835 char const *test16_descr[] = {
00836 "Varargs initialization without running the thread. Just calls",
00837 "QT_VARGS.",
00838 ":: varargs 4 init = QT_VARGS(4 args)",
00839 NULL
00840 };
00841
00842
00843 void
00844 test16 (int n)
00845 {
00846 thread_t main;
00847 thread_t *t;
00848
00849 t = t_alloc();
00850 t->next = &main;
00851
00852 while (--n >= 0) {
00853 test10_init (t, &main, 4 * sizeof(int), 4, 3, 2, 1);
00854 }
00855 t_free (t);
00856 }
00857
00858
00859 char const test17_msg[] = { "*Test varargs initialization w/ 8 args." };
00860
00861 char const *test17_descr[] = {
00862 "Varargs initialization without running the thread. Just calls",
00863 "QT_VARGS.",
00864 ":: varargs 8 init = QT_VARGS(8 args)",
00865 NULL
00866 };
00867
00868
00869 void
00870 test17 (int n)
00871 {
00872 thread_t main;
00873 thread_t *t;
00874
00875 t = t_alloc();
00876 t->next = &main;
00877
00878 while (--n >= 0) {
00879 test10_init (t, &main, 8 * sizeof(int), 8, 7, 6, 5, 4, 3, 2, 1);
00880 }
00881 t_free (t);
00882 }
00883
00884
00885
00886 char const test18_msg[] = { "*Call register indirect." };
00887 char const *test18_descr[] = { NULL };
00888
00889 void
00890 test18 (int n)
00891 {
00892 b_call_reg (n);
00893 }
00894
00895
00896 char const test19_msg[] = { "*Call immediate." };
00897 char const *test19_descr[] = { NULL };
00898
00899 void
00900 test19 (int n)
00901 {
00902 b_call_imm (n);
00903 }
00904
00905
00906 char const test20_msg[] = { "*Add register-to-register." };
00907 char const *test20_descr[] = { NULL };
00908
00909 void
00910 test20 (int n)
00911 {
00912 b_add (n);
00913 }
00914
00915
00916 char const test21_msg[] = { "*Load memory to a register." };
00917 char const *test21_descr[] = { NULL };
00918
00919 void
00920 test21 (int n)
00921 {
00922 b_load (n);
00923 }
00924
00925
00926
00927 typedef struct foo_t {
00928 char const *msg;
00929 char const **descr;
00930 void (*f)(int n);
00931 } foo_t;
00932
00933
00934 static foo_t foo[] = {
00935 { "Usage:\n", NULL, (void(*)(int n))usage },
00936 { test01_msg, test01_descr, test01 },
00937 { test02_msg, NULL, test02 },
00938 { test03_msg, NULL, test03 },
00939 { test04_msg, NULL, test04 },
00940 { test05_msg, NULL, test05 },
00941 { test06_msg, test06_descr, test06 },
00942 { test07_msg, test07_descr, test07 },
00943 { test08_msg, test08_descr, test08 },
00944 { test09_msg, NULL, test09 },
00945 { test10_msg, test10_descr, test10 },
00946 { test11_msg, test11_descr, test11 },
00947 { test12_msg, test12_descr, test12 },
00948 { test13_msg, test13_descr, test13 },
00949 { test14_msg, test14_descr, test14 },
00950 { test15_msg, test15_descr, test15 },
00951 { test16_msg, test16_descr, test16 },
00952 { test17_msg, test17_descr, test17 },
00953 { test18_msg, test18_descr, test18 },
00954 { test19_msg, test19_descr, test19 },
00955 { test20_msg, test20_descr, test20 },
00956 { test21_msg, test21_descr, test21 },
00957 { 0, 0 }
00958 };
00959
00960 static int tv = 0;
00961
00962 void
00963 tracer ()
00964 {
00965
00966 fprintf (stderr, "tracer\t%d\n", tv++);
00967 fflush (stderr);
00968 }
00969
00970 void
00971 tracer2 (void *val)
00972 {
00973 fprintf (stderr, "tracer2\t%d val=0x%p", tv++, val);
00974 fflush (stderr);
00975 }
00976
00977
00978 void
00979 describe()
00980 {
00981 int i;
00982 FILE *out = stdout;
00983
00984 for (i=0; foo[i].msg; ++i) {
00985 if (foo[i].descr) {
00986 int j;
00987
00988 putc ('\n', out);
00989 fprintf (out, "[%d]\n", i);
00990 for (j=0; foo[i].descr[j]; ++j) {
00991 fputs (foo[i].descr[j], out);
00992 putc ('\n', out);
00993 }
00994 }
00995 }
00996 exit (0);
00997 }
00998
00999
01000 void
01001 usage()
01002 {
01003 int i;
01004
01005 fputs (foo[0].msg, stderr);
01006 for (i=1; foo[i].msg; ++i) {
01007 fprintf (stderr, "%2d\t%s\n", i, foo[i].msg);
01008 }
01009 exit (1);
01010 }
01011
01012
01013 void
01014 args (int *which, int *n, int argc, char **argv)
01015 {
01016 static int nfuncs = 0;
01017
01018 if (argc == 2 && argv[1][0] == '-' && argv[1][1] == 'h') {
01019 describe();
01020 }
01021
01022 if (nfuncs == 0) {
01023 for (nfuncs=0; foo[nfuncs].msg; ++nfuncs)
01024 ;
01025 }
01026
01027 if (argc != 2 && argc != 3) {
01028 usage();
01029 }
01030
01031 *which = atoi (argv[1]);
01032 if (*which < 0 || *which >= nfuncs) {
01033 usage();
01034 }
01035 *n = (argc == 3)
01036 ? atoi (argv[2])
01037 : 1;
01038 }
01039
01040
01041 int
01042 main (int argc, char **argv)
01043 {
01044 int which, n;
01045 args (&which, &n, argc, argv);
01046 (*(foo[which].f))(n);
01047 exit (0);
01048 return (0);
01049 }