123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050 |
- /* meas.c -- measure qt stuff. */
- #include "copyright.h"
- /* Need this to get assertions under Mach on the Sequent/i386: */
- #ifdef __i386__
- #define assert(ex) \
- do { \
- if (!(ex)) { \
- fprintf (stderr, "[%s:%d] Assertion " #ex " failed\n", __FILE__, __LINE__); \
- abort(); \
- } \
- } while (0)
- #else
- #include <assert.h>
- #endif
- /* This really ought to be defined in some ANSI include file (*I*
- think...), but it's defined here instead, which leads us to another
- machine dependency.
- The `iaddr_t' type is an integer representation of a pointer,
- suited for doing arithmetic on addresses, e.g. to round an address
- to an alignment boundary. */
- typedef unsigned long iaddr_t;
- #include <stdarg.h> /* For varargs tryout. */
- #include <stdio.h>
- #include "b.h"
- #include "qt.h"
- #include "stp.h"
- extern void exit (int status);
- extern int atoi (char const *s);
- extern int fprintf (FILE *out, char const *fmt, ...);
- extern int fputs (char const *s, FILE *fp);
- extern void free (void *sto);
- extern void *malloc (unsigned nbytes);
- extern void perror (char const *s);
- void usage (void);
- void tracer(void);
- /* Round `v' to be `a'-aligned, assuming `a' is a power of two. */
- #define ROUND(v, a) (((v) + (a) - 1) & ~((a)-1))
- typedef struct thread_t {
- qt_t *qt; /* Pointer to thread of function... */
- void *stk;
- void *top; /* Set top of stack if reuse. */
- struct thread_t *next;
- } thread_t;
- static thread_t *
- t_alloc (void)
- {
- thread_t *t;
- int ssz = 0x1000;
- t = malloc (sizeof(thread_t));
- if (!t) {
- perror ("malloc");
- exit (1);
- }
- assert (ssz > QT_STKBASE);
- t->stk = malloc (ssz);
- t->stk = (void *)ROUND (((iaddr_t)t->stk), QT_STKALIGN);
- if (!t->stk) {
- perror ("malloc");
- exit (1);
- }
- assert ((((iaddr_t)t->stk) & (QT_STKALIGN-1)) == 0);
- t->top = QT_SP (t->stk, ssz - QT_STKBASE);
- return (t);
- }
- static thread_t *
- t_create (qt_only_t *starter, void *p0, qt_userf_t *f)
- {
- thread_t *t;
- t = t_alloc();
- t->qt = QT_ARGS (t->top, p0, t, f, starter);
- return (t);
- }
- static void
- t_free (thread_t *t)
- {
- free (t->stk);
- free (t);
- }
- static void *
- t_null (qt_t *old, void *p1, void *p2)
- {
- /* return (garbage); */
- }
- static void *
- t_splat (qt_t *old, void *oldp, void *null)
- {
- *(qt_t **)oldp = old;
- /* return (garbage); */
- }
- static char const test01_msg[] =
- "*QT_SP(sto,sz), QT_ARGS(top,p0,p1,userf,first)";
- static char const *test01_descr[] = {
- "Performs 1 QT_SP and one QT_ARGS per iteration.",
- NULL
- };
- /* This test gives a guess on how long it takes to initalize
- a thread. */
- static void
- test01 (int n)
- {
- char stack[QT_STKBASE+QT_STKALIGN];
- char *stk;
- qt_t *top;
- stk = (char *)ROUND (((iaddr_t)stack), QT_STKALIGN);
- {
- int i;
- for (i=0; i<QT_STKBASE; ++i) {
- stk[i] = 0;
- }
- }
- while (n>0) {
- /* RETVALUSED */
- top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
- #ifdef NDEF
- top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
- top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
- top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
- top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
- top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
- top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
- top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
- top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
- top = QT_SP (stk, QT_STKBASE); QT_ARGS (top, 0, 0, 0, 0);
- n -= 10;
- #else
- n -= 1;
- #endif
- }
- }
- static char const test02_msg[] = "QT_BLOCKI (0, 0, test02_aux, t->qt)";
- static qt_t *rootthread;
- static void
- test02_aux1 (void *pu, void *pt, qt_userf_t *f)
- {
- QT_ABORT (t_null, 0, 0, rootthread);
- }
- static void *
- test02_aux2 (qt_t *old, void *farg1, void *farg2)
- {
- rootthread = old;
- /* return (garbage); */
- }
- static void
- test02 (int n)
- {
- thread_t *t;
- while (n>0) {
- t = t_create (test02_aux1, 0, 0);
- QT_BLOCKI (test02_aux2, 0, 0, t->qt);
- t_free (t);
- t = t_create (test02_aux1, 0, 0);
- QT_BLOCKI (test02_aux2, 0, 0, t->qt);
- t_free (t);
- t = t_create (test02_aux1, 0, 0);
- QT_BLOCKI (test02_aux2, 0, 0, t->qt);
- t_free (t);
- t = t_create (test02_aux1, 0, 0);
- QT_BLOCKI (test02_aux2, 0, 0, t->qt);
- t_free (t);
- t = t_create (test02_aux1, 0, 0);
- QT_BLOCKI (test02_aux2, 0, 0, t->qt);
- t_free (t);
- n -= 5;
- }
- }
- static char const test03_msg[] = "QT_BLOCKI (...) test vals are right.";
- /* Called by the thread function when it wants to shut down.
- Return a value to the main thread. */
- static void *
- test03_aux0 (qt_t *old_is_garbage, void *farg1, void *farg2)
- {
- assert (farg1 == (void *)5);
- assert (farg2 == (void *)6);
- return ((void *)15); /* Some unlikely value. */
- }
- /* Called during new thread startup by main thread. Since the new
- thread has never run before, return value is ignored. */
- static void *
- test03_aux1 (qt_t *old, void *farg1, void *farg2)
- {
- assert (old != NULL);
- assert (farg1 == (void *)5);
- assert (farg2 == (void *)6);
- rootthread = old;
- return ((void *)16); /* Different than `15'. */
- }
- static void
- test03_aux2 (void *pu, void *pt, qt_userf_t *f)
- {
- assert (pu == (void *)1);
- assert (f == (qt_userf_t *)4);
- QT_ABORT (test03_aux0, (void *)5, (void *)6, rootthread);
- }
- static void
- test03 (int n)
- {
- thread_t *t;
- void *rv;
- while (n>0) {
- t = t_create (test03_aux2, (void *)1, (qt_userf_t *)4);
- rv = QT_BLOCKI (test03_aux1, (void *)5, (void *)6, t->qt);
- assert (rv == (void *)15);
- t_free (t);
- --n;
- }
- }
- static char const test04_msg[] = "stp_start w/ no threads.";
- static void
- test04 (int n)
- {
- while (n>0) {
- stp_init(); stp_start();
- stp_init(); stp_start();
- stp_init(); stp_start();
- stp_init(); stp_start();
- stp_init(); stp_start();
- stp_init(); stp_start();
- stp_init(); stp_start();
- stp_init(); stp_start();
- stp_init(); stp_start();
- stp_init(); stp_start();
- n -= 10;
- }
- }
- static char const test05_msg[] = "stp w/ 2 yielding thread.";
- static void
- test05_aux (void *null)
- {
- stp_yield();
- stp_yield();
- }
- static void
- test05 (int n)
- {
- while (n>0) {
- stp_init();
- stp_create (test05_aux, 0);
- stp_create (test05_aux, 0);
- stp_start();
- --n;
- }
- }
- static char const test06_msg[] = "*QT_ARGS(...), QT_BLOCKI one thread";
- static char const *test06_descr[] = {
- "Does a QT_ARGS, QT_BLOCKI to a helper function that saves the",
- "stack pointer of the main thread, calls an `only' function that",
- "saves aborts the thread, calling a null helper function.",
- ":: start/stop = QT_ARGS + QT_BLOCKI + QT_ABORT + 3 procedure calls.",
- NULL
- };
- /* This test initializes a thread, runs it, then returns to the main
- program, which reinitializes the thread, runs it again, etc. Each
- iteration corresponds to 1 init, 1 abort, 1 block. */
- static qt_t *test06_sp;
- static void
- test06_aux2 (void *null0a, void *null1b, void *null2b, qt_userf_t *null)
- {
- QT_ABORT (t_null, 0, 0, test06_sp);
- }
- static void *
- test06_aux3 (qt_t *sp, void *null0c, void *null1c)
- {
- test06_sp = sp;
- /* return (garbage); */
- }
- static void
- test06 (int n)
- {
- thread_t *t;
- t = t_create (0, 0, 0);
- while (n>0) {
- /* RETVALUSED */
- QT_ARGS (t->top, 0, 0, 0, test06_aux2);
- QT_BLOCKI (test06_aux3, 0, 0, t->qt);
- #ifdef NDEF
- /* RETVALUSED */
- QT_ARGS (t->top, 0, 0, 0, test06_aux2);
- QT_BLOCKI (test06_aux3, 0, 0, t->qt);
- /* RETVALUSED */
- QT_ARGS (t->top, 0, 0, 0, test06_aux2);
- QT_BLOCKI (test06_aux3, 0, 0, t->qt);
- /* RETVALUSED */
- QT_ARGS (t->top, 0, 0, 0, test06_aux2);
- QT_BLOCKI (test06_aux3, 0, 0, t->qt);
- /* RETVALUSED */
- QT_ARGS (t->top, 0, 0, 0, test06_aux2);
- QT_BLOCKI (test06_aux3, 0, 0, t->qt);
- n -= 5;
- #else
- --n;
- #endif
- }
- }
- static char test07_msg[] = "*cswap between threads";
- static char const *test07_descr[] = {
- "Build a chain of threads where each thread has a fixed successor.",
- "There is no scheduling performed. Each thread but one is a loop",
- "that simply blocks with QT_BLOCKI, calling a helper that saves the",
- "current stack pointer. The last thread decrements a count, and,",
- "if zero, aborts back to the main thread. Else it continues with",
- "the blocking chain. The count is divided by the number of threads",
- "in the chain, so `n' is the number of integer block operations.",
- ":: integer cswap = QT_BLOCKI + a procedure call.",
- NULL
- };
- /* This test repeatedly blocks a bunch of threads.
- Each iteration corresponds to one block operation.
- The threads are arranged so that there are TEST07_N-1 of them that
- run `test07_aux2'. Each one of those blocks saving it's sp to
- storage owned by the preceding thread; a pointer to that storage is
- passed in via `mep'. Each thread has a handle on it's own storage
- for the next thread, referenced by `nxtp', and it blocks by passing
- control to `*nxtp', telling the helper function to save its state
- in `*mep'. The last thread in the chain decrements a count and, if
- it's gone below zero, returns to `test07'; otherwise, it invokes
- the first thread in the chain. */
- static qt_t *test07_heavy;
- #define TEST07_N (4)
- static void
- test07_aux2 (void *null0, void *mep, void *nxtp, qt_userf_t *null)
- {
- qt_t *nxt;
- while (1) {
- nxt = *(qt_t **)nxtp;
- #ifdef NDEF
- printf ("Helper 0x%p\n", nxtp);
- #endif
- QT_BLOCKI (t_splat, mep, 0, nxt);
- }
- }
- static void
- test07_aux3 (void *np, void *mep, void *nxtp, qt_userf_t *null)
- {
- int n;
- n = *(int *)np;
- while (1) {
- n -= TEST07_N;
- if (n<0) {
- QT_ABORT (t_splat, mep, 0, test07_heavy);
- }
- QT_BLOCKI (t_splat, mep, 0, *(qt_t **)nxtp);
- }
- }
- static void
- test07 (int n)
- {
- int i;
- thread_t *t[TEST07_N];
- for (i=0; i<TEST07_N; ++i) {
- t[i] = t_create (0, 0, 0);
- }
- for (i=0; i<TEST07_N-1; ++i) {
- /* RETVALUSED */
- QT_ARGS (t[i]->top, 0, &t[i]->qt, &t[i+1]->qt, test07_aux2);
- }
- /* RETVALUSED */
- QT_ARGS (t[i]->top, &n, &t[TEST07_N-1]->qt, &t[0]->qt, test07_aux3);
- QT_BLOCKI (t_splat, &test07_heavy, 0, t[0]->qt);
- }
- static char test08_msg[] = "Floating-point cswap between threads";
- static char const *test08_descr[] = {
- "Measure context switch times including floating-point, use QT_BLOCK.",
- NULL
- };
- static qt_t *test08_heavy;
- #define TEST08_N (4)
- static void
- test08_aux2 (void *null0, void *mep, void *nxtp, qt_userf_t *null)
- {
- qt_t *nxt;
- while (1) {
- nxt = *(qt_t **)nxtp;
- QT_BLOCK (t_splat, mep, 0, nxt);
- }
- }
- static void
- test08_aux3 (void *np, void *mep, void *nxtp, qt_userf_t *null)
- {
- int n;
- n = *(int *)np;
- while (1) {
- n -= TEST08_N;
- if (n<0) {
- QT_ABORT (t_splat, mep, 0, test08_heavy);
- }
- QT_BLOCK (t_splat, mep, 0, *(qt_t **)nxtp);
- }
- }
- static void
- test08 (int n)
- {
- int i;
- thread_t *t[TEST08_N];
- for (i=0; i<TEST08_N; ++i) {
- t[i] = t_create (0, 0, 0);
- }
- for (i=0; i<TEST08_N-1; ++i) {
- /* RETVALUSED */
- QT_ARGS (t[i]->top, 0, &t[i]->qt, &t[i+1]->qt, test08_aux2);
- }
- /* RETVALUSED */
- QT_ARGS (t[i]->top, &n, &t[TEST08_N-1]->qt, &t[0]->qt, test08_aux3);
- QT_BLOCK (t_splat, &test08_heavy, 0, t[0]->qt);
- }
- /* Test the varargs procedure calling. */
- char const test09_msg[] = { "Start and run threads using varargs." };
- thread_t *test09_t0, *test09_t1, *test09_t2, *test09_main;
- thread_t *
- test09_create (qt_startup_t *start, qt_vuserf_t *f,
- qt_cleanup_t *cleanup, int nbytes, ...)
- {
- va_list ap;
- thread_t *t;
- t = t_alloc();
- va_start (ap, nbytes);
- t->qt = QT_VARGS (t->top, nbytes, ap, t, start, f, cleanup);
- va_end (ap);
- return (t);
- }
- static void
- test09_cleanup (void *pt, void *vuserf_retval)
- {
- assert (vuserf_retval == (void *)17);
- QT_ABORT (t_splat, &((thread_t *)pt)->qt, 0,
- ((thread_t *)pt)->next->qt);
- }
- static void
- test09_start (void *pt)
- {
- }
- static void *
- test09_user0 (void)
- {
- QT_BLOCKI (t_splat, &test09_t0->qt, 0, test09_t1->qt);
- return ((void *)17);
- }
- static void *
- test09_user2 (int one, int two)
- {
- assert (one == 1);
- assert (two == 2);
- QT_BLOCKI (t_splat, &test09_t1->qt, 0, test09_t2->qt);
- assert (one == 1);
- assert (two == 2);
- return ((void *)17);
- }
- static void *
- test09_user10 (int one, int two, int three, int four, int five,
- int six, int seven, int eight, int nine, int ten)
- {
- assert (one == 1);
- assert (two == 2);
- assert (three == 3);
- assert (four == 4);
- assert (five == 5);
- assert (six == 6);
- assert (seven == 7);
- assert (eight == 8);
- assert (nine == 9);
- assert (ten == 10);
- QT_BLOCKI (t_splat, &test09_t2->qt, 0, test09_main->qt);
- assert (one == 1);
- assert (two == 2);
- assert (three == 3);
- assert (four == 4);
- assert (five == 5);
- assert (six == 6);
- assert (seven == 7);
- assert (eight == 8);
- assert (nine == 9);
- assert (ten == 10);
- return ((void *)17);
- }
- void
- test09 (int n)
- {
- thread_t main;
- test09_main = &main;
- while (--n >= 0) {
- test09_t0 = test09_create (test09_start, (qt_vuserf_t*)test09_user0,
- test09_cleanup, 0);
- test09_t1 = test09_create (test09_start, (qt_vuserf_t*)test09_user2,
- test09_cleanup, 2 * sizeof(qt_word_t), 1, 2);
- test09_t2 = test09_create (test09_start, (qt_vuserf_t*)test09_user10,
- test09_cleanup, 10 * sizeof(qt_word_t),
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
- /* Chaining used by `test09_cleanup' to determine who is next. */
- test09_t0->next = test09_t1;
- test09_t1->next = test09_t2;
- test09_t2->next = test09_main;
- QT_BLOCKI (t_splat, &test09_main->qt, 0, test09_t0->qt);
- QT_BLOCKI (t_splat, &test09_main->qt, 0, test09_t0->qt);
- t_free (test09_t0);
- t_free (test09_t1);
- t_free (test09_t2);
- }
- }
- /* Test 10/11/12: time the cost of various number of args. */
- char const test10_msg[] = { "*Test varargs init & startup w/ 0 args." };
- char const *test10_descr[] = {
- "Start and stop threads that use variant argument lists (varargs).",
- "Each thread is initialized by calling a routine that calls",
- "QT_VARARGS. Then runs the thread by calling QT_BLOCKI to hald the",
- "main thread, a helper that saves the main thread's stack pointer,",
- "a null startup function, a null user function, a cleanup function",
- "that calls QT_ABORT and restarts the main thread. Copies no user",
- "parameters.",
- ":: varargs start/stop = QT_BLOCKI + QT_ABORT + 6 function calls.",
- NULL
- };
- /* Helper function to send control back to main.
- Don't save anything. */
- /* Helper function for starting the varargs thread. Save the stack
- pointer of the main thread so we can get back there eventually. */
- /* Startup function for a varargs thread. */
- static void
- test10_startup (void *pt)
- {
- }
- /* User function for a varargs thread. */
- static void *
- test10_run (int arg0, ...)
- {
- /* return (garbage); */
- }
- /* Cleanup function for a varargs thread. Send control
- back to the main thread. Don't save any state from the thread that
- is halting. */
- void
- test10_cleanup (void *pt, void *vuserf_retval)
- {
- QT_ABORT (t_null, 0, 0, ((thread_t *)pt)->qt);
- }
- void
- test10_init (thread_t *new, thread_t *next, int nbytes, ...)
- {
- va_list ap;
- va_start (ap, nbytes);
- new->qt = QT_VARGS (new->top, nbytes, ap, next, test10_startup,
- test10_run, test10_cleanup);
- va_end (ap);
- }
- void
- test10 (int n)
- {
- thread_t main;
- thread_t *t;
- t = t_alloc();
- t->next = &main;
- while (--n >= 0) {
- test10_init (t, &main, 0);
- QT_BLOCKI (t_splat, &main.qt, 0, t->qt);
- }
- t_free (t);
- }
- char const test11_msg[] = { "*Test varargs init & startup w/ 2 args." };
- char const *test11_descr[] = {
- "Varargs initialization/run. Copies 2 user arguments.",
- ":: varargs 2 start/stop = QT_VARGS(2 args), QT_BLOCKI, QT_ABORT, 6 f() calls.",
- NULL
- };
- void
- test11 (int n)
- {
- thread_t main;
- thread_t *t;
- t = t_alloc();
- t->next = &main;
- while (--n >= 0) {
- test10_init (t, &main, 2 * sizeof(int), 2, 1);
- QT_BLOCKI (t_splat, &main.qt, 0, t->qt);
- }
- t_free (t);
- }
- char const test12_msg[] = { "*Test varargs init & startup w/ 4 args." };
- char const *test12_descr[] = {
- "Varargs initialization/run. Copies 4 user arguments.",
- ":: varargs 4 start/stop = QT_VARGS(4 args), QT_BLOCKI, QT_ABORT, 6 f() calls.",
- NULL
- };
- void
- test12 (int n)
- {
- thread_t main;
- thread_t *t;
- t = t_alloc();
- t->next = &main;
- while (--n >= 0) {
- test10_init (t, &main, 4 * sizeof(int), 4, 3, 2, 1);
- QT_BLOCKI (t_splat, &main.qt, 0, t->qt);
- }
- t_free (t);
- }
- char const test13_msg[] = { "*Test varargs init & startup w/ 8 args." };
- char const *test13_descr[] = {
- "Varargs initialization/run. Copies 8 user arguments.",
- ":: varargs 8 start/stop = QT_VARGS(8 args), QT_BLOCKI, QT_ABORT, 6 f() calls.",
- NULL
- };
- void
- test13 (int n)
- {
- thread_t main;
- thread_t *t;
- t = t_alloc();
- t->next = &main;
- while (--n >= 0) {
- test10_init (t, &main, 8 * sizeof(int), 8, 7, 6, 5, 4, 3, 2, 1);
- QT_BLOCKI (t_splat, &main.qt, 0, t->qt);
- }
- t_free (t);
- }
- char const test14_msg[] = { "*Test varargs initialization w/ 0 args." };
- char const *test14_descr[] = {
- "Varargs initialization without running the thread. Just calls",
- "QT_VARGS.",
- ":: varargs 0 init = QT_VARGS()",
- NULL
- };
- void
- test14 (int n)
- {
- thread_t main;
- thread_t *t;
- t = t_alloc();
- t->next = &main;
- while (--n >= 0) {
- test10_init (t, &main, 0 * sizeof(int));
- }
- t_free (t);
- }
- char const test15_msg[] = { "*Test varargs initialization w/ 2 args." };
- char const *test15_descr[] = {
- "Varargs initialization without running the thread. Just calls",
- "QT_VARGS.",
- ":: varargs 2 init = QT_VARGS(2 args)",
- NULL
- };
- void
- test15 (int n)
- {
- thread_t main;
- thread_t *t;
- t = t_alloc();
- t->next = &main;
- while (--n >= 0) {
- test10_init (t, &main, 2 * sizeof(int), 2, 1);
- }
- t_free (t);
- }
- char const test16_msg[] = { "*Test varargs initialization w/ 4 args." };
- char const *test16_descr[] = {
- "Varargs initialization without running the thread. Just calls",
- "QT_VARGS.",
- ":: varargs 4 init = QT_VARGS(4 args)",
- NULL
- };
- void
- test16 (int n)
- {
- thread_t main;
- thread_t *t;
- t = t_alloc();
- t->next = &main;
- while (--n >= 0) {
- test10_init (t, &main, 4 * sizeof(int), 4, 3, 2, 1);
- }
- t_free (t);
- }
- char const test17_msg[] = { "*Test varargs initialization w/ 8 args." };
- char const *test17_descr[] = {
- "Varargs initialization without running the thread. Just calls",
- "QT_VARGS.",
- ":: varargs 8 init = QT_VARGS(8 args)",
- NULL
- };
- void
- test17 (int n)
- {
- thread_t main;
- thread_t *t;
- t = t_alloc();
- t->next = &main;
- while (--n >= 0) {
- test10_init (t, &main, 8 * sizeof(int), 8, 7, 6, 5, 4, 3, 2, 1);
- }
- t_free (t);
- }
- /* Test times for basic machine operations. */
- char const test18_msg[] = { "*Call register indirect." };
- char const *test18_descr[] = { NULL };
- void
- test18 (int n)
- {
- b_call_reg (n);
- }
- char const test19_msg[] = { "*Call immediate." };
- char const *test19_descr[] = { NULL };
- void
- test19 (int n)
- {
- b_call_imm (n);
- }
- char const test20_msg[] = { "*Add register-to-register." };
- char const *test20_descr[] = { NULL };
- void
- test20 (int n)
- {
- b_add (n);
- }
- char const test21_msg[] = { "*Load memory to a register." };
- char const *test21_descr[] = { NULL };
- void
- test21 (int n)
- {
- b_load (n);
- }
- /* Driver. */
- typedef struct foo_t {
- char const *msg; /* Message to print for generic help. */
- char const **descr; /* A description of what is done by the test. */
- void (*f)(int n);
- } foo_t;
- static foo_t foo[] = {
- { "Usage:\n", NULL, (void(*)(int n))usage },
- { test01_msg, test01_descr, test01 },
- { test02_msg, NULL, test02 },
- { test03_msg, NULL, test03 },
- { test04_msg, NULL, test04 },
- { test05_msg, NULL, test05 },
- { test06_msg, test06_descr, test06 },
- { test07_msg, test07_descr, test07 },
- { test08_msg, test08_descr, test08 },
- { test09_msg, NULL, test09 },
- { test10_msg, test10_descr, test10 },
- { test11_msg, test11_descr, test11 },
- { test12_msg, test12_descr, test12 },
- { test13_msg, test13_descr, test13 },
- { test14_msg, test14_descr, test14 },
- { test15_msg, test15_descr, test15 },
- { test16_msg, test16_descr, test16 },
- { test17_msg, test17_descr, test17 },
- { test18_msg, test18_descr, test18 },
- { test19_msg, test19_descr, test19 },
- { test20_msg, test20_descr, test20 },
- { test21_msg, test21_descr, test21 },
- { 0, 0 }
- };
- static int tv = 0;
- void
- tracer ()
- {
- fprintf (stderr, "tracer\t%d\n", tv++);
- fflush (stderr);
- }
- void
- tracer2 (void *val)
- {
- fprintf (stderr, "tracer2\t%d val=0x%p", tv++, val);
- fflush (stderr);
- }
- void
- describe()
- {
- int i;
- FILE *out = stdout;
- for (i=0; foo[i].msg; ++i) {
- if (foo[i].descr) {
- int j;
- putc ('\n', out);
- fprintf (out, "[%d]\n", i);
- for (j=0; foo[i].descr[j]; ++j) {
- fputs (foo[i].descr[j], out);
- putc ('\n', out);
- }
- }
- }
- exit (0);
- }
- void
- usage()
- {
- int i;
- fputs (foo[0].msg, stderr);
- for (i=1; foo[i].msg; ++i) {
- fprintf (stderr, "%2d\t%s\n", i, foo[i].msg);
- }
- exit (1);
- }
- void
- args (int *which, int *n, int argc, char **argv)
- {
- static int nfuncs = 0;
- if (argc == 2 && argv[1][0] == '-' && argv[1][1] == 'h') {
- describe();
- }
- if (nfuncs == 0) {
- for (nfuncs=0; foo[nfuncs].msg; ++nfuncs)
- ;
- }
- if (argc != 2 && argc != 3) {
- usage();
- }
- *which = atoi (argv[1]);
- if (*which < 0 || *which >= nfuncs) {
- usage();
- }
- *n = (argc == 3)
- ? atoi (argv[2])
- : 1;
- }
- int
- main (int argc, char **argv)
- {
- int which, n;
- args (&which, &n, argc, argv);
- (*(foo[which].f))(n);
- exit (0);
- return (0);
- }
|