112027Sjungma@eit.uni-kl.de/* meas.c -- measure qt stuff. */
212027Sjungma@eit.uni-kl.de
312027Sjungma@eit.uni-kl.de#include "copyright.h"
412027Sjungma@eit.uni-kl.de
512027Sjungma@eit.uni-kl.de/* Need this to get assertions under Mach on the Sequent/i386: */
612027Sjungma@eit.uni-kl.de#ifdef __i386__
712027Sjungma@eit.uni-kl.de#define assert(ex) \
812027Sjungma@eit.uni-kl.de  do { \
912027Sjungma@eit.uni-kl.de    if (!(ex)) { \
1012027Sjungma@eit.uni-kl.de      fprintf (stderr, "[%s:%d] Assertion " #ex " failed\n", __FILE__, __LINE__); \
1112027Sjungma@eit.uni-kl.de      abort(); \
1212027Sjungma@eit.uni-kl.de    } \
1312027Sjungma@eit.uni-kl.de  } while (0)
1412027Sjungma@eit.uni-kl.de#else
1512027Sjungma@eit.uni-kl.de#include <assert.h>
1612027Sjungma@eit.uni-kl.de#endif
1712027Sjungma@eit.uni-kl.de
1812027Sjungma@eit.uni-kl.de/* This really ought to be defined in some ANSI include file (*I*
1912027Sjungma@eit.uni-kl.de   think...), but it's defined here instead, which leads us to another
2012027Sjungma@eit.uni-kl.de   machine dependency.
2112027Sjungma@eit.uni-kl.de
2212027Sjungma@eit.uni-kl.de   The `iaddr_t' type is an integer representation of a pointer,
2312027Sjungma@eit.uni-kl.de   suited for doing arithmetic on addresses, e.g. to round an address
2412027Sjungma@eit.uni-kl.de   to an alignment boundary. */
2512027Sjungma@eit.uni-kl.detypedef unsigned long iaddr_t;
2612027Sjungma@eit.uni-kl.de
2712027Sjungma@eit.uni-kl.de#include <stdarg.h>	/* For varargs tryout. */
2812027Sjungma@eit.uni-kl.de#include <stdio.h>
2912027Sjungma@eit.uni-kl.de#include "b.h"
3012027Sjungma@eit.uni-kl.de#include "qt.h"
3112027Sjungma@eit.uni-kl.de#include "stp.h"
3212027Sjungma@eit.uni-kl.de
3312027Sjungma@eit.uni-kl.deextern void exit (int status);
3412027Sjungma@eit.uni-kl.deextern int atoi (char const *s);
3512027Sjungma@eit.uni-kl.deextern int fprintf (FILE *out, char const *fmt, ...);
3612027Sjungma@eit.uni-kl.deextern int fputs (char const *s, FILE *fp);
3712027Sjungma@eit.uni-kl.deextern void free (void *sto);
3812027Sjungma@eit.uni-kl.deextern void *malloc (unsigned nbytes);
3912027Sjungma@eit.uni-kl.deextern void perror (char const *s);
4012027Sjungma@eit.uni-kl.de
4112027Sjungma@eit.uni-kl.devoid usage (void);
4212027Sjungma@eit.uni-kl.devoid tracer(void);
4312027Sjungma@eit.uni-kl.de
4412027Sjungma@eit.uni-kl.de/* Round `v' to be `a'-aligned, assuming `a' is a power of two. */
4512027Sjungma@eit.uni-kl.de#define ROUND(v, a)	(((v) + (a) - 1) & ~((a)-1))
4612027Sjungma@eit.uni-kl.de
4712027Sjungma@eit.uni-kl.detypedef struct thread_t {
4812027Sjungma@eit.uni-kl.de  qt_t *qt;		/* Pointer to thread of function... */
4912027Sjungma@eit.uni-kl.de  void *stk;
5012027Sjungma@eit.uni-kl.de  void *top;		/* Set top of stack if reuse. */
5112027Sjungma@eit.uni-kl.de  struct thread_t *next;
5212027Sjungma@eit.uni-kl.de} thread_t;
5312027Sjungma@eit.uni-kl.de
5412027Sjungma@eit.uni-kl.de
5512027Sjungma@eit.uni-kl.de  static thread_t *
5612027Sjungma@eit.uni-kl.det_alloc (void)
5712027Sjungma@eit.uni-kl.de{
5812027Sjungma@eit.uni-kl.de  thread_t *t;
5912027Sjungma@eit.uni-kl.de  int ssz = 0x1000;
6012027Sjungma@eit.uni-kl.de
6112027Sjungma@eit.uni-kl.de  t = malloc (sizeof(thread_t));
6212027Sjungma@eit.uni-kl.de  if (!t) {
6312027Sjungma@eit.uni-kl.de    perror ("malloc");
6412027Sjungma@eit.uni-kl.de    exit (1);
6512027Sjungma@eit.uni-kl.de  }
6612027Sjungma@eit.uni-kl.de  assert (ssz > QT_STKBASE);
6712027Sjungma@eit.uni-kl.de  t->stk = malloc (ssz);
6812027Sjungma@eit.uni-kl.de  t->stk = (void *)ROUND (((iaddr_t)t->stk), QT_STKALIGN);
6912027Sjungma@eit.uni-kl.de  if (!t->stk) {
7012027Sjungma@eit.uni-kl.de    perror ("malloc");
7112027Sjungma@eit.uni-kl.de    exit (1);
7212027Sjungma@eit.uni-kl.de  }
7312027Sjungma@eit.uni-kl.de  assert ((((iaddr_t)t->stk) & (QT_STKALIGN-1)) == 0);
7412027Sjungma@eit.uni-kl.de  t->top = QT_SP (t->stk, ssz - QT_STKBASE);
7512027Sjungma@eit.uni-kl.de
7612027Sjungma@eit.uni-kl.de  return (t);
7712027Sjungma@eit.uni-kl.de}
7812027Sjungma@eit.uni-kl.de
7912027Sjungma@eit.uni-kl.de
8012027Sjungma@eit.uni-kl.de  static thread_t *
8112027Sjungma@eit.uni-kl.det_create (qt_only_t *starter, void *p0, qt_userf_t *f)
8212027Sjungma@eit.uni-kl.de{
8312027Sjungma@eit.uni-kl.de  thread_t *t;
8412027Sjungma@eit.uni-kl.de
8512027Sjungma@eit.uni-kl.de  t = t_alloc();
8612027Sjungma@eit.uni-kl.de  t->qt = QT_ARGS (t->top, p0, t, f, starter);
8712027Sjungma@eit.uni-kl.de  return (t);
8812027Sjungma@eit.uni-kl.de}
8912027Sjungma@eit.uni-kl.de
9012027Sjungma@eit.uni-kl.de
9112027Sjungma@eit.uni-kl.de  static void
9212027Sjungma@eit.uni-kl.det_free (thread_t *t)
9312027Sjungma@eit.uni-kl.de{
9412027Sjungma@eit.uni-kl.de  free (t->stk);
9512027Sjungma@eit.uni-kl.de  free (t);
9612027Sjungma@eit.uni-kl.de}
9712027Sjungma@eit.uni-kl.de
9812027Sjungma@eit.uni-kl.de
9912027Sjungma@eit.uni-kl.de  static void *
10012027Sjungma@eit.uni-kl.det_null (qt_t *old, void *p1, void *p2)
10112027Sjungma@eit.uni-kl.de{
10212027Sjungma@eit.uni-kl.de  /* return (garbage); */
10312027Sjungma@eit.uni-kl.de}
10412027Sjungma@eit.uni-kl.de
10512027Sjungma@eit.uni-kl.de
10612027Sjungma@eit.uni-kl.de  static void *
10712027Sjungma@eit.uni-kl.det_splat (qt_t *old, void *oldp, void *null)
10812027Sjungma@eit.uni-kl.de{
10912027Sjungma@eit.uni-kl.de  *(qt_t **)oldp = old;
11012027Sjungma@eit.uni-kl.de  /* return (garbage); */
11112027Sjungma@eit.uni-kl.de}
11212027Sjungma@eit.uni-kl.de
11312027Sjungma@eit.uni-kl.de
11412027Sjungma@eit.uni-kl.destatic char const test01_msg[] =
11512027Sjungma@eit.uni-kl.de  "*QT_SP(sto,sz), QT_ARGS(top,p0,p1,userf,first)";
11612027Sjungma@eit.uni-kl.de
11712027Sjungma@eit.uni-kl.destatic char const *test01_descr[] = {
11812027Sjungma@eit.uni-kl.de  "Performs 1 QT_SP and one QT_ARGS per iteration.",
11912027Sjungma@eit.uni-kl.de  NULL
12012027Sjungma@eit.uni-kl.de};
12112027Sjungma@eit.uni-kl.de
12212027Sjungma@eit.uni-kl.de/* This test gives a guess on how long it takes to initalize
12312027Sjungma@eit.uni-kl.de   a thread. */
12412027Sjungma@eit.uni-kl.de
12512027Sjungma@eit.uni-kl.de  static void
12612027Sjungma@eit.uni-kl.detest01 (int n)
12712027Sjungma@eit.uni-kl.de{
12812027Sjungma@eit.uni-kl.de  char stack[QT_STKBASE+QT_STKALIGN];
12912027Sjungma@eit.uni-kl.de  char *stk;
13012027Sjungma@eit.uni-kl.de  qt_t *top;
13112027Sjungma@eit.uni-kl.de
13212027Sjungma@eit.uni-kl.de  stk = (char *)ROUND (((iaddr_t)stack), QT_STKALIGN);
13312027Sjungma@eit.uni-kl.de
13412027Sjungma@eit.uni-kl.de  {
13512027Sjungma@eit.uni-kl.de    int i;
13612027Sjungma@eit.uni-kl.de
13712027Sjungma@eit.uni-kl.de    for (i=0; i<QT_STKBASE; ++i) {
13812027Sjungma@eit.uni-kl.de      stk[i] = 0;
13912027Sjungma@eit.uni-kl.de    }
14012027Sjungma@eit.uni-kl.de  }
14112027Sjungma@eit.uni-kl.de
14212027Sjungma@eit.uni-kl.de  while (n>0) {
14312027Sjungma@eit.uni-kl.de    /* RETVALUSED */
14412027Sjungma@eit.uni-kl.de    top = QT_SP (stk, QT_STKBASE);	QT_ARGS (top, 0, 0, 0, 0);
14512027Sjungma@eit.uni-kl.de#ifdef NDEF
14612027Sjungma@eit.uni-kl.de    top = QT_SP (stk, QT_STKBASE);	QT_ARGS (top, 0, 0, 0, 0);
14712027Sjungma@eit.uni-kl.de    top = QT_SP (stk, QT_STKBASE);	QT_ARGS (top, 0, 0, 0, 0);
14812027Sjungma@eit.uni-kl.de    top = QT_SP (stk, QT_STKBASE);	QT_ARGS (top, 0, 0, 0, 0);
14912027Sjungma@eit.uni-kl.de    top = QT_SP (stk, QT_STKBASE);	QT_ARGS (top, 0, 0, 0, 0);
15012027Sjungma@eit.uni-kl.de
15112027Sjungma@eit.uni-kl.de    top = QT_SP (stk, QT_STKBASE);	QT_ARGS (top, 0, 0, 0, 0);
15212027Sjungma@eit.uni-kl.de    top = QT_SP (stk, QT_STKBASE);	QT_ARGS (top, 0, 0, 0, 0);
15312027Sjungma@eit.uni-kl.de    top = QT_SP (stk, QT_STKBASE);	QT_ARGS (top, 0, 0, 0, 0);
15412027Sjungma@eit.uni-kl.de    top = QT_SP (stk, QT_STKBASE);	QT_ARGS (top, 0, 0, 0, 0);
15512027Sjungma@eit.uni-kl.de    top = QT_SP (stk, QT_STKBASE);	QT_ARGS (top, 0, 0, 0, 0);
15612027Sjungma@eit.uni-kl.de
15712027Sjungma@eit.uni-kl.de    n -= 10;
15812027Sjungma@eit.uni-kl.de#else
15912027Sjungma@eit.uni-kl.de    n -= 1;
16012027Sjungma@eit.uni-kl.de#endif
16112027Sjungma@eit.uni-kl.de  }
16212027Sjungma@eit.uni-kl.de}
16312027Sjungma@eit.uni-kl.de
16412027Sjungma@eit.uni-kl.de
16512027Sjungma@eit.uni-kl.destatic char const test02_msg[] = "QT_BLOCKI (0, 0, test02_aux, t->qt)";
16612027Sjungma@eit.uni-kl.destatic qt_t *rootthread;
16712027Sjungma@eit.uni-kl.de
16812027Sjungma@eit.uni-kl.de  static void
16912027Sjungma@eit.uni-kl.detest02_aux1 (void *pu, void *pt, qt_userf_t *f)
17012027Sjungma@eit.uni-kl.de{
17112027Sjungma@eit.uni-kl.de  QT_ABORT (t_null, 0, 0, rootthread);
17212027Sjungma@eit.uni-kl.de}
17312027Sjungma@eit.uni-kl.de
17412027Sjungma@eit.uni-kl.de  static void *
17512027Sjungma@eit.uni-kl.detest02_aux2 (qt_t *old, void *farg1, void *farg2)
17612027Sjungma@eit.uni-kl.de{
17712027Sjungma@eit.uni-kl.de  rootthread = old;
17812027Sjungma@eit.uni-kl.de  /* return (garbage); */
17912027Sjungma@eit.uni-kl.de}
18012027Sjungma@eit.uni-kl.de
18112027Sjungma@eit.uni-kl.de  static void
18212027Sjungma@eit.uni-kl.detest02 (int n)
18312027Sjungma@eit.uni-kl.de{
18412027Sjungma@eit.uni-kl.de  thread_t *t;
18512027Sjungma@eit.uni-kl.de
18612027Sjungma@eit.uni-kl.de  while (n>0) {
18712027Sjungma@eit.uni-kl.de  t = t_create (test02_aux1, 0, 0);
18812027Sjungma@eit.uni-kl.de    QT_BLOCKI (test02_aux2, 0, 0, t->qt);
18912027Sjungma@eit.uni-kl.de  t_free (t);
19012027Sjungma@eit.uni-kl.de  t = t_create (test02_aux1, 0, 0);
19112027Sjungma@eit.uni-kl.de    QT_BLOCKI (test02_aux2, 0, 0, t->qt);
19212027Sjungma@eit.uni-kl.de  t_free (t);
19312027Sjungma@eit.uni-kl.de  t = t_create (test02_aux1, 0, 0);
19412027Sjungma@eit.uni-kl.de    QT_BLOCKI (test02_aux2, 0, 0, t->qt);
19512027Sjungma@eit.uni-kl.de  t_free (t);
19612027Sjungma@eit.uni-kl.de  t = t_create (test02_aux1, 0, 0);
19712027Sjungma@eit.uni-kl.de    QT_BLOCKI (test02_aux2, 0, 0, t->qt);
19812027Sjungma@eit.uni-kl.de  t_free (t);
19912027Sjungma@eit.uni-kl.de  t = t_create (test02_aux1, 0, 0);
20012027Sjungma@eit.uni-kl.de    QT_BLOCKI (test02_aux2, 0, 0, t->qt);
20112027Sjungma@eit.uni-kl.de  t_free (t);
20212027Sjungma@eit.uni-kl.de
20312027Sjungma@eit.uni-kl.de    n -= 5;
20412027Sjungma@eit.uni-kl.de  }
20512027Sjungma@eit.uni-kl.de}
20612027Sjungma@eit.uni-kl.de
20712027Sjungma@eit.uni-kl.de
20812027Sjungma@eit.uni-kl.destatic char const test03_msg[] = "QT_BLOCKI (...) test vals are right.";
20912027Sjungma@eit.uni-kl.de
21012027Sjungma@eit.uni-kl.de
21112027Sjungma@eit.uni-kl.de/* Called by the thread function when it wants to shut down.
21212027Sjungma@eit.uni-kl.de   Return a value to the main thread. */
21312027Sjungma@eit.uni-kl.de
21412027Sjungma@eit.uni-kl.de  static void *
21512027Sjungma@eit.uni-kl.detest03_aux0 (qt_t *old_is_garbage, void *farg1, void *farg2)
21612027Sjungma@eit.uni-kl.de{
21712027Sjungma@eit.uni-kl.de  assert (farg1 == (void *)5);
21812027Sjungma@eit.uni-kl.de  assert (farg2 == (void *)6);
21912027Sjungma@eit.uni-kl.de  return ((void *)15);		/* Some unlikely value. */
22012027Sjungma@eit.uni-kl.de}
22112027Sjungma@eit.uni-kl.de
22212027Sjungma@eit.uni-kl.de
22312027Sjungma@eit.uni-kl.de/* Called during new thread startup by main thread.  Since the new
22412027Sjungma@eit.uni-kl.de   thread has never run before, return value is ignored. */
22512027Sjungma@eit.uni-kl.de
22612027Sjungma@eit.uni-kl.de  static void *
22712027Sjungma@eit.uni-kl.detest03_aux1 (qt_t *old, void *farg1, void *farg2)
22812027Sjungma@eit.uni-kl.de{
22912027Sjungma@eit.uni-kl.de  assert (old != NULL);
23012027Sjungma@eit.uni-kl.de  assert (farg1 == (void *)5);
23112027Sjungma@eit.uni-kl.de  assert (farg2 == (void *)6);
23212027Sjungma@eit.uni-kl.de  rootthread = old;
23312027Sjungma@eit.uni-kl.de  return ((void *)16);		/* Different than `15'. */
23412027Sjungma@eit.uni-kl.de}
23512027Sjungma@eit.uni-kl.de
23612027Sjungma@eit.uni-kl.de  static void
23712027Sjungma@eit.uni-kl.detest03_aux2 (void *pu, void *pt, qt_userf_t *f)
23812027Sjungma@eit.uni-kl.de{
23912027Sjungma@eit.uni-kl.de  assert (pu == (void *)1);
24012027Sjungma@eit.uni-kl.de  assert (f == (qt_userf_t *)4);
24112027Sjungma@eit.uni-kl.de  QT_ABORT (test03_aux0, (void *)5, (void *)6, rootthread);
24212027Sjungma@eit.uni-kl.de}
24312027Sjungma@eit.uni-kl.de
24412027Sjungma@eit.uni-kl.de  static void
24512027Sjungma@eit.uni-kl.detest03 (int n)
24612027Sjungma@eit.uni-kl.de{
24712027Sjungma@eit.uni-kl.de  thread_t *t;
24812027Sjungma@eit.uni-kl.de  void *rv;
24912027Sjungma@eit.uni-kl.de
25012027Sjungma@eit.uni-kl.de  while (n>0) {
25112027Sjungma@eit.uni-kl.de    t = t_create (test03_aux2, (void *)1, (qt_userf_t *)4);
25212027Sjungma@eit.uni-kl.de    rv = QT_BLOCKI (test03_aux1, (void *)5, (void *)6, t->qt);
25312027Sjungma@eit.uni-kl.de    assert (rv == (void *)15);
25412027Sjungma@eit.uni-kl.de    t_free (t);
25512027Sjungma@eit.uni-kl.de
25612027Sjungma@eit.uni-kl.de    --n;
25712027Sjungma@eit.uni-kl.de  }
25812027Sjungma@eit.uni-kl.de}
25912027Sjungma@eit.uni-kl.de
26012027Sjungma@eit.uni-kl.de
26112027Sjungma@eit.uni-kl.destatic char const test04_msg[] = "stp_start w/ no threads.";
26212027Sjungma@eit.uni-kl.de
26312027Sjungma@eit.uni-kl.de  static void
26412027Sjungma@eit.uni-kl.detest04 (int n)
26512027Sjungma@eit.uni-kl.de{
26612027Sjungma@eit.uni-kl.de  while (n>0) {
26712027Sjungma@eit.uni-kl.de    stp_init();	stp_start();
26812027Sjungma@eit.uni-kl.de    stp_init();	stp_start();
26912027Sjungma@eit.uni-kl.de    stp_init();	stp_start();
27012027Sjungma@eit.uni-kl.de    stp_init();	stp_start();
27112027Sjungma@eit.uni-kl.de    stp_init();	stp_start();
27212027Sjungma@eit.uni-kl.de
27312027Sjungma@eit.uni-kl.de    stp_init();	stp_start();
27412027Sjungma@eit.uni-kl.de    stp_init();	stp_start();
27512027Sjungma@eit.uni-kl.de    stp_init();	stp_start();
27612027Sjungma@eit.uni-kl.de    stp_init();	stp_start();
27712027Sjungma@eit.uni-kl.de    stp_init();	stp_start();
27812027Sjungma@eit.uni-kl.de
27912027Sjungma@eit.uni-kl.de    n -= 10;
28012027Sjungma@eit.uni-kl.de  }
28112027Sjungma@eit.uni-kl.de}
28212027Sjungma@eit.uni-kl.de
28312027Sjungma@eit.uni-kl.de
28412027Sjungma@eit.uni-kl.destatic char const test05_msg[] = "stp w/ 2 yielding thread.";
28512027Sjungma@eit.uni-kl.de
28612027Sjungma@eit.uni-kl.de  static void
28712027Sjungma@eit.uni-kl.detest05_aux (void *null)
28812027Sjungma@eit.uni-kl.de{
28912027Sjungma@eit.uni-kl.de  stp_yield();
29012027Sjungma@eit.uni-kl.de  stp_yield();
29112027Sjungma@eit.uni-kl.de}
29212027Sjungma@eit.uni-kl.de
29312027Sjungma@eit.uni-kl.de  static void
29412027Sjungma@eit.uni-kl.detest05 (int n)
29512027Sjungma@eit.uni-kl.de{
29612027Sjungma@eit.uni-kl.de  while (n>0) {
29712027Sjungma@eit.uni-kl.de    stp_init();
29812027Sjungma@eit.uni-kl.de    stp_create (test05_aux, 0);
29912027Sjungma@eit.uni-kl.de    stp_create (test05_aux, 0);
30012027Sjungma@eit.uni-kl.de    stp_start();
30112027Sjungma@eit.uni-kl.de
30212027Sjungma@eit.uni-kl.de    --n;
30312027Sjungma@eit.uni-kl.de  }
30412027Sjungma@eit.uni-kl.de}
30512027Sjungma@eit.uni-kl.de
30612027Sjungma@eit.uni-kl.de
30712027Sjungma@eit.uni-kl.destatic char const test06_msg[] = "*QT_ARGS(...), QT_BLOCKI one thread";
30812027Sjungma@eit.uni-kl.de
30912027Sjungma@eit.uni-kl.destatic char const *test06_descr[] = {
31012027Sjungma@eit.uni-kl.de  "Does a QT_ARGS, QT_BLOCKI to a helper function that saves the",
31112027Sjungma@eit.uni-kl.de  "stack pointer of the main thread, calls an `only' function that",
31212027Sjungma@eit.uni-kl.de  "saves aborts the thread, calling a null helper function.",
31312027Sjungma@eit.uni-kl.de  ":: start/stop = QT_ARGS + QT_BLOCKI + QT_ABORT + 3 procedure calls.",
31412027Sjungma@eit.uni-kl.de  NULL
31512027Sjungma@eit.uni-kl.de};
31612027Sjungma@eit.uni-kl.de
31712027Sjungma@eit.uni-kl.de/* This test initializes a thread, runs it, then returns to the main
31812027Sjungma@eit.uni-kl.de   program, which reinitializes the thread, runs it again, etc.  Each
31912027Sjungma@eit.uni-kl.de   iteration corresponds to 1 init, 1 abort, 1 block. */
32012027Sjungma@eit.uni-kl.de
32112027Sjungma@eit.uni-kl.destatic qt_t *test06_sp;
32212027Sjungma@eit.uni-kl.de
32312027Sjungma@eit.uni-kl.de
32412027Sjungma@eit.uni-kl.de  static void
32512027Sjungma@eit.uni-kl.detest06_aux2 (void *null0a, void *null1b, void *null2b, qt_userf_t *null)
32612027Sjungma@eit.uni-kl.de{
32712027Sjungma@eit.uni-kl.de  QT_ABORT (t_null, 0, 0, test06_sp);
32812027Sjungma@eit.uni-kl.de}
32912027Sjungma@eit.uni-kl.de
33012027Sjungma@eit.uni-kl.de
33112027Sjungma@eit.uni-kl.de  static void *
33212027Sjungma@eit.uni-kl.detest06_aux3 (qt_t *sp, void *null0c, void *null1c)
33312027Sjungma@eit.uni-kl.de{
33412027Sjungma@eit.uni-kl.de  test06_sp = sp;
33512027Sjungma@eit.uni-kl.de  /* return (garbage); */
33612027Sjungma@eit.uni-kl.de}
33712027Sjungma@eit.uni-kl.de
33812027Sjungma@eit.uni-kl.de
33912027Sjungma@eit.uni-kl.de  static void
34012027Sjungma@eit.uni-kl.detest06 (int n)
34112027Sjungma@eit.uni-kl.de{
34212027Sjungma@eit.uni-kl.de  thread_t *t;
34312027Sjungma@eit.uni-kl.de
34412027Sjungma@eit.uni-kl.de  t = t_create (0, 0, 0);
34512027Sjungma@eit.uni-kl.de
34612027Sjungma@eit.uni-kl.de  while (n>0) {
34712027Sjungma@eit.uni-kl.de    /* RETVALUSED */
34812027Sjungma@eit.uni-kl.de    QT_ARGS (t->top, 0, 0, 0, test06_aux2);
34912027Sjungma@eit.uni-kl.de    QT_BLOCKI (test06_aux3, 0, 0, t->qt);
35012027Sjungma@eit.uni-kl.de#ifdef NDEF
35112027Sjungma@eit.uni-kl.de    /* RETVALUSED */
35212027Sjungma@eit.uni-kl.de    QT_ARGS (t->top, 0, 0, 0, test06_aux2);
35312027Sjungma@eit.uni-kl.de    QT_BLOCKI (test06_aux3, 0, 0, t->qt);
35412027Sjungma@eit.uni-kl.de
35512027Sjungma@eit.uni-kl.de    /* RETVALUSED */
35612027Sjungma@eit.uni-kl.de    QT_ARGS (t->top, 0, 0, 0, test06_aux2);
35712027Sjungma@eit.uni-kl.de    QT_BLOCKI (test06_aux3, 0, 0, t->qt);
35812027Sjungma@eit.uni-kl.de
35912027Sjungma@eit.uni-kl.de    /* RETVALUSED */
36012027Sjungma@eit.uni-kl.de    QT_ARGS (t->top, 0, 0, 0, test06_aux2);
36112027Sjungma@eit.uni-kl.de    QT_BLOCKI (test06_aux3, 0, 0, t->qt);
36212027Sjungma@eit.uni-kl.de
36312027Sjungma@eit.uni-kl.de    /* RETVALUSED */
36412027Sjungma@eit.uni-kl.de    QT_ARGS (t->top, 0, 0, 0, test06_aux2);
36512027Sjungma@eit.uni-kl.de    QT_BLOCKI (test06_aux3, 0, 0, t->qt);
36612027Sjungma@eit.uni-kl.de
36712027Sjungma@eit.uni-kl.de    n -= 5;
36812027Sjungma@eit.uni-kl.de#else
36912027Sjungma@eit.uni-kl.de    --n;
37012027Sjungma@eit.uni-kl.de#endif
37112027Sjungma@eit.uni-kl.de  }
37212027Sjungma@eit.uni-kl.de}
37312027Sjungma@eit.uni-kl.de
37412027Sjungma@eit.uni-kl.destatic char test07_msg[] = "*cswap between threads";
37512027Sjungma@eit.uni-kl.de
37612027Sjungma@eit.uni-kl.destatic char const *test07_descr[] = {
37712027Sjungma@eit.uni-kl.de  "Build a chain of threads where each thread has a fixed successor.",
37812027Sjungma@eit.uni-kl.de  "There is no scheduling performed.  Each thread but one is a loop",
37912027Sjungma@eit.uni-kl.de  "that simply blocks with QT_BLOCKI, calling a helper that saves the",
38012027Sjungma@eit.uni-kl.de  "current stack pointer.  The last thread decrements a count, and,",
38112027Sjungma@eit.uni-kl.de  "if zero, aborts back to the main thread.  Else it continues with",
38212027Sjungma@eit.uni-kl.de  "the blocking chain.  The count is divided by the number of threads",
38312027Sjungma@eit.uni-kl.de  "in the chain, so `n' is the number of integer block operations.",
38412027Sjungma@eit.uni-kl.de  ":: integer cswap = QT_BLOCKI + a procedure call.",
38512027Sjungma@eit.uni-kl.de  NULL
38612027Sjungma@eit.uni-kl.de};
38712027Sjungma@eit.uni-kl.de
38812027Sjungma@eit.uni-kl.de/* This test repeatedly blocks a bunch of threads.
38912027Sjungma@eit.uni-kl.de   Each iteration corresponds to one block operation.
39012027Sjungma@eit.uni-kl.de
39112027Sjungma@eit.uni-kl.de   The threads are arranged so that there are TEST07_N-1 of them that
39212027Sjungma@eit.uni-kl.de   run `test07_aux2'.  Each one of those blocks saving it's sp to
39312027Sjungma@eit.uni-kl.de   storage owned by the preceding thread; a pointer to that storage is
39412027Sjungma@eit.uni-kl.de   passed in via `mep'.  Each thread has a handle on it's own storage
39512027Sjungma@eit.uni-kl.de   for the next thread, referenced by `nxtp', and it blocks by passing
39612027Sjungma@eit.uni-kl.de   control to `*nxtp', telling the helper function to save its state
39712027Sjungma@eit.uni-kl.de   in `*mep'.  The last thread in the chain decrements a count and, if
39812027Sjungma@eit.uni-kl.de   it's gone below zero, returns to `test07'; otherwise, it invokes
39912027Sjungma@eit.uni-kl.de   the first thread in the chain. */
40012027Sjungma@eit.uni-kl.de
40112027Sjungma@eit.uni-kl.destatic qt_t *test07_heavy;
40212027Sjungma@eit.uni-kl.de
40312027Sjungma@eit.uni-kl.de#define TEST07_N (4)
40412027Sjungma@eit.uni-kl.de
40512027Sjungma@eit.uni-kl.de
40612027Sjungma@eit.uni-kl.de  static void
40712027Sjungma@eit.uni-kl.detest07_aux2 (void *null0, void *mep, void *nxtp, qt_userf_t *null)
40812027Sjungma@eit.uni-kl.de{
40912027Sjungma@eit.uni-kl.de  qt_t *nxt;
41012027Sjungma@eit.uni-kl.de
41112027Sjungma@eit.uni-kl.de  while (1) {
41212027Sjungma@eit.uni-kl.de    nxt = *(qt_t **)nxtp;
41312027Sjungma@eit.uni-kl.de#ifdef NDEF
41412027Sjungma@eit.uni-kl.de    printf ("Helper 0x%p\n", nxtp);
41512027Sjungma@eit.uni-kl.de#endif
41612027Sjungma@eit.uni-kl.de    QT_BLOCKI (t_splat, mep, 0, nxt);
41712027Sjungma@eit.uni-kl.de  }
41812027Sjungma@eit.uni-kl.de}
41912027Sjungma@eit.uni-kl.de
42012027Sjungma@eit.uni-kl.de  static void
42112027Sjungma@eit.uni-kl.detest07_aux3 (void *np, void *mep, void *nxtp, qt_userf_t *null)
42212027Sjungma@eit.uni-kl.de{
42312027Sjungma@eit.uni-kl.de  int n;
42412027Sjungma@eit.uni-kl.de
42512027Sjungma@eit.uni-kl.de  n = *(int *)np;
42612027Sjungma@eit.uni-kl.de  while (1) {
42712027Sjungma@eit.uni-kl.de    n -= TEST07_N;
42812027Sjungma@eit.uni-kl.de    if (n<0) {
42912027Sjungma@eit.uni-kl.de      QT_ABORT (t_splat, mep, 0, test07_heavy);
43012027Sjungma@eit.uni-kl.de    }
43112027Sjungma@eit.uni-kl.de    QT_BLOCKI (t_splat, mep, 0, *(qt_t **)nxtp);
43212027Sjungma@eit.uni-kl.de  }
43312027Sjungma@eit.uni-kl.de}
43412027Sjungma@eit.uni-kl.de
43512027Sjungma@eit.uni-kl.de
43612027Sjungma@eit.uni-kl.de  static void
43712027Sjungma@eit.uni-kl.detest07 (int n)
43812027Sjungma@eit.uni-kl.de{
43912027Sjungma@eit.uni-kl.de  int i;
44012027Sjungma@eit.uni-kl.de  thread_t *t[TEST07_N];
44112027Sjungma@eit.uni-kl.de
44212027Sjungma@eit.uni-kl.de  for (i=0; i<TEST07_N; ++i) {
44312027Sjungma@eit.uni-kl.de    t[i] = t_create (0, 0, 0);
44412027Sjungma@eit.uni-kl.de  }
44512027Sjungma@eit.uni-kl.de  for (i=0; i<TEST07_N-1; ++i) {
44612027Sjungma@eit.uni-kl.de    /* RETVALUSED */
44712027Sjungma@eit.uni-kl.de    QT_ARGS (t[i]->top, 0, &t[i]->qt, &t[i+1]->qt, test07_aux2);
44812027Sjungma@eit.uni-kl.de  }
44912027Sjungma@eit.uni-kl.de  /* RETVALUSED */
45012027Sjungma@eit.uni-kl.de  QT_ARGS (t[i]->top, &n, &t[TEST07_N-1]->qt, &t[0]->qt, test07_aux3);
45112027Sjungma@eit.uni-kl.de  QT_BLOCKI (t_splat, &test07_heavy, 0, t[0]->qt);
45212027Sjungma@eit.uni-kl.de}
45312027Sjungma@eit.uni-kl.de
45412027Sjungma@eit.uni-kl.de
45512027Sjungma@eit.uni-kl.destatic char test08_msg[] = "Floating-point cswap between threads";
45612027Sjungma@eit.uni-kl.de
45712027Sjungma@eit.uni-kl.destatic char const *test08_descr[] = {
45812027Sjungma@eit.uni-kl.de  "Measure context switch times including floating-point, use QT_BLOCK.",
45912027Sjungma@eit.uni-kl.de  NULL
46012027Sjungma@eit.uni-kl.de};
46112027Sjungma@eit.uni-kl.de
46212027Sjungma@eit.uni-kl.destatic qt_t *test08_heavy;
46312027Sjungma@eit.uni-kl.de
46412027Sjungma@eit.uni-kl.de#define TEST08_N (4)
46512027Sjungma@eit.uni-kl.de
46612027Sjungma@eit.uni-kl.de
46712027Sjungma@eit.uni-kl.de  static void
46812027Sjungma@eit.uni-kl.detest08_aux2 (void *null0, void *mep, void *nxtp, qt_userf_t *null)
46912027Sjungma@eit.uni-kl.de{
47012027Sjungma@eit.uni-kl.de  qt_t *nxt;
47112027Sjungma@eit.uni-kl.de
47212027Sjungma@eit.uni-kl.de  while (1) {
47312027Sjungma@eit.uni-kl.de    nxt = *(qt_t **)nxtp;
47412027Sjungma@eit.uni-kl.de    QT_BLOCK (t_splat, mep, 0, nxt);
47512027Sjungma@eit.uni-kl.de  }
47612027Sjungma@eit.uni-kl.de}
47712027Sjungma@eit.uni-kl.de
47812027Sjungma@eit.uni-kl.de  static void
47912027Sjungma@eit.uni-kl.detest08_aux3 (void *np, void *mep, void *nxtp, qt_userf_t *null)
48012027Sjungma@eit.uni-kl.de{
48112027Sjungma@eit.uni-kl.de  int n;
48212027Sjungma@eit.uni-kl.de
48312027Sjungma@eit.uni-kl.de  n = *(int *)np;
48412027Sjungma@eit.uni-kl.de  while (1) {
48512027Sjungma@eit.uni-kl.de    n -= TEST08_N;
48612027Sjungma@eit.uni-kl.de    if (n<0) {
48712027Sjungma@eit.uni-kl.de      QT_ABORT (t_splat, mep, 0, test08_heavy);
48812027Sjungma@eit.uni-kl.de    }
48912027Sjungma@eit.uni-kl.de    QT_BLOCK (t_splat, mep, 0, *(qt_t **)nxtp);
49012027Sjungma@eit.uni-kl.de  }
49112027Sjungma@eit.uni-kl.de}
49212027Sjungma@eit.uni-kl.de
49312027Sjungma@eit.uni-kl.de
49412027Sjungma@eit.uni-kl.de  static void
49512027Sjungma@eit.uni-kl.detest08 (int n)
49612027Sjungma@eit.uni-kl.de{
49712027Sjungma@eit.uni-kl.de  int i;
49812027Sjungma@eit.uni-kl.de  thread_t *t[TEST08_N];
49912027Sjungma@eit.uni-kl.de
50012027Sjungma@eit.uni-kl.de  for (i=0; i<TEST08_N; ++i) {
50112027Sjungma@eit.uni-kl.de    t[i] = t_create (0, 0, 0);
50212027Sjungma@eit.uni-kl.de  }
50312027Sjungma@eit.uni-kl.de  for (i=0; i<TEST08_N-1; ++i) {
50412027Sjungma@eit.uni-kl.de    /* RETVALUSED */
50512027Sjungma@eit.uni-kl.de    QT_ARGS (t[i]->top, 0, &t[i]->qt, &t[i+1]->qt, test08_aux2);
50612027Sjungma@eit.uni-kl.de  }
50712027Sjungma@eit.uni-kl.de  /* RETVALUSED */
50812027Sjungma@eit.uni-kl.de  QT_ARGS (t[i]->top, &n, &t[TEST08_N-1]->qt, &t[0]->qt, test08_aux3);
50912027Sjungma@eit.uni-kl.de  QT_BLOCK (t_splat, &test08_heavy, 0, t[0]->qt);
51012027Sjungma@eit.uni-kl.de}
51112027Sjungma@eit.uni-kl.de
51212027Sjungma@eit.uni-kl.de
51312027Sjungma@eit.uni-kl.de/* Test the varargs procedure calling. */
51412027Sjungma@eit.uni-kl.de
51512027Sjungma@eit.uni-kl.dechar const test09_msg[] = { "Start and run threads using varargs." };
51612027Sjungma@eit.uni-kl.de
51712027Sjungma@eit.uni-kl.dethread_t *test09_t0, *test09_t1, *test09_t2, *test09_main;
51812027Sjungma@eit.uni-kl.de
51912027Sjungma@eit.uni-kl.de  thread_t *
52012027Sjungma@eit.uni-kl.detest09_create (qt_startup_t *start, qt_vuserf_t *f,
52112027Sjungma@eit.uni-kl.de	       qt_cleanup_t *cleanup, int nbytes, ...)
52212027Sjungma@eit.uni-kl.de{
52312027Sjungma@eit.uni-kl.de  va_list ap;
52412027Sjungma@eit.uni-kl.de  thread_t *t;
52512027Sjungma@eit.uni-kl.de
52612027Sjungma@eit.uni-kl.de  t = t_alloc();
52712027Sjungma@eit.uni-kl.de  va_start (ap, nbytes);
52812027Sjungma@eit.uni-kl.de  t->qt = QT_VARGS (t->top, nbytes, ap, t, start, f, cleanup);
52912027Sjungma@eit.uni-kl.de  va_end (ap);
53012027Sjungma@eit.uni-kl.de  return (t);
53112027Sjungma@eit.uni-kl.de}
53212027Sjungma@eit.uni-kl.de
53312027Sjungma@eit.uni-kl.de
53412027Sjungma@eit.uni-kl.de  static void
53512027Sjungma@eit.uni-kl.detest09_cleanup (void *pt, void *vuserf_retval)
53612027Sjungma@eit.uni-kl.de{
53712027Sjungma@eit.uni-kl.de  assert (vuserf_retval == (void *)17);
53812027Sjungma@eit.uni-kl.de  QT_ABORT (t_splat, &((thread_t *)pt)->qt, 0,
53912027Sjungma@eit.uni-kl.de	    ((thread_t *)pt)->next->qt);
54012027Sjungma@eit.uni-kl.de}
54112027Sjungma@eit.uni-kl.de
54212027Sjungma@eit.uni-kl.de
54312027Sjungma@eit.uni-kl.de  static void
54412027Sjungma@eit.uni-kl.detest09_start (void *pt)
54512027Sjungma@eit.uni-kl.de{
54612027Sjungma@eit.uni-kl.de}
54712027Sjungma@eit.uni-kl.de
54812027Sjungma@eit.uni-kl.de
54912027Sjungma@eit.uni-kl.de  static void *
55012027Sjungma@eit.uni-kl.detest09_user0 (void)
55112027Sjungma@eit.uni-kl.de{
55212027Sjungma@eit.uni-kl.de  QT_BLOCKI (t_splat, &test09_t0->qt, 0, test09_t1->qt);
55312027Sjungma@eit.uni-kl.de  return ((void *)17);
55412027Sjungma@eit.uni-kl.de}
55512027Sjungma@eit.uni-kl.de
55612027Sjungma@eit.uni-kl.de  static void *
55712027Sjungma@eit.uni-kl.detest09_user2 (int one, int two)
55812027Sjungma@eit.uni-kl.de{
55912027Sjungma@eit.uni-kl.de  assert (one == 1);
56012027Sjungma@eit.uni-kl.de  assert (two == 2);
56112027Sjungma@eit.uni-kl.de  QT_BLOCKI (t_splat, &test09_t1->qt, 0, test09_t2->qt);
56212027Sjungma@eit.uni-kl.de  assert (one == 1);
56312027Sjungma@eit.uni-kl.de  assert (two == 2);
56412027Sjungma@eit.uni-kl.de  return ((void *)17);
56512027Sjungma@eit.uni-kl.de}
56612027Sjungma@eit.uni-kl.de
56712027Sjungma@eit.uni-kl.de  static void *
56812027Sjungma@eit.uni-kl.detest09_user10 (int one, int two, int three, int four, int five,
56912027Sjungma@eit.uni-kl.de	      int six, int seven, int eight, int nine, int ten)
57012027Sjungma@eit.uni-kl.de{
57112027Sjungma@eit.uni-kl.de  assert (one == 1);
57212027Sjungma@eit.uni-kl.de  assert (two == 2);
57312027Sjungma@eit.uni-kl.de  assert (three == 3);
57412027Sjungma@eit.uni-kl.de  assert (four == 4);
57512027Sjungma@eit.uni-kl.de  assert (five == 5);
57612027Sjungma@eit.uni-kl.de  assert (six == 6);
57712027Sjungma@eit.uni-kl.de  assert (seven == 7);
57812027Sjungma@eit.uni-kl.de  assert (eight == 8);
57912027Sjungma@eit.uni-kl.de  assert (nine == 9);
58012027Sjungma@eit.uni-kl.de  assert (ten == 10);
58112027Sjungma@eit.uni-kl.de  QT_BLOCKI (t_splat, &test09_t2->qt, 0, test09_main->qt);
58212027Sjungma@eit.uni-kl.de  assert (one == 1);
58312027Sjungma@eit.uni-kl.de  assert (two == 2);
58412027Sjungma@eit.uni-kl.de  assert (three == 3);
58512027Sjungma@eit.uni-kl.de  assert (four == 4);
58612027Sjungma@eit.uni-kl.de  assert (five == 5);
58712027Sjungma@eit.uni-kl.de  assert (six == 6);
58812027Sjungma@eit.uni-kl.de  assert (seven == 7);
58912027Sjungma@eit.uni-kl.de  assert (eight == 8);
59012027Sjungma@eit.uni-kl.de  assert (nine == 9);
59112027Sjungma@eit.uni-kl.de  assert (ten == 10);
59212027Sjungma@eit.uni-kl.de  return ((void *)17);
59312027Sjungma@eit.uni-kl.de}
59412027Sjungma@eit.uni-kl.de
59512027Sjungma@eit.uni-kl.de
59612027Sjungma@eit.uni-kl.de  void
59712027Sjungma@eit.uni-kl.detest09 (int n)
59812027Sjungma@eit.uni-kl.de{
59912027Sjungma@eit.uni-kl.de  thread_t main;
60012027Sjungma@eit.uni-kl.de
60112027Sjungma@eit.uni-kl.de  test09_main = &main;
60212027Sjungma@eit.uni-kl.de
60312027Sjungma@eit.uni-kl.de  while (--n >= 0) {
60412027Sjungma@eit.uni-kl.de    test09_t0 = test09_create (test09_start, (qt_vuserf_t*)test09_user0,
60512027Sjungma@eit.uni-kl.de			       test09_cleanup, 0);
60612027Sjungma@eit.uni-kl.de    test09_t1 = test09_create (test09_start, (qt_vuserf_t*)test09_user2,
60712027Sjungma@eit.uni-kl.de			       test09_cleanup, 2 * sizeof(qt_word_t), 1, 2);
60812027Sjungma@eit.uni-kl.de    test09_t2 = test09_create (test09_start, (qt_vuserf_t*)test09_user10,
60912027Sjungma@eit.uni-kl.de			       test09_cleanup, 10 * sizeof(qt_word_t),
61012027Sjungma@eit.uni-kl.de			       1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
61112027Sjungma@eit.uni-kl.de
61212027Sjungma@eit.uni-kl.de    /* Chaining used by `test09_cleanup' to determine who is next. */
61312027Sjungma@eit.uni-kl.de    test09_t0->next = test09_t1;
61412027Sjungma@eit.uni-kl.de    test09_t1->next = test09_t2;
61512027Sjungma@eit.uni-kl.de    test09_t2->next = test09_main;
61612027Sjungma@eit.uni-kl.de
61712027Sjungma@eit.uni-kl.de    QT_BLOCKI (t_splat, &test09_main->qt, 0, test09_t0->qt);
61812027Sjungma@eit.uni-kl.de    QT_BLOCKI (t_splat, &test09_main->qt, 0, test09_t0->qt);
61912027Sjungma@eit.uni-kl.de
62012027Sjungma@eit.uni-kl.de    t_free (test09_t0);
62112027Sjungma@eit.uni-kl.de    t_free (test09_t1);
62212027Sjungma@eit.uni-kl.de    t_free (test09_t2);
62312027Sjungma@eit.uni-kl.de  }
62412027Sjungma@eit.uni-kl.de}
62512027Sjungma@eit.uni-kl.de
62612027Sjungma@eit.uni-kl.de
62712027Sjungma@eit.uni-kl.de/* Test 10/11/12: time the cost of various number of args. */
62812027Sjungma@eit.uni-kl.de
62912027Sjungma@eit.uni-kl.dechar const test10_msg[] = { "*Test varargs init & startup w/ 0 args." };
63012027Sjungma@eit.uni-kl.de
63112027Sjungma@eit.uni-kl.dechar const *test10_descr[] = {
63212027Sjungma@eit.uni-kl.de  "Start and stop threads that use variant argument lists (varargs).",
63312027Sjungma@eit.uni-kl.de  "Each thread is initialized by calling a routine that calls",
63412027Sjungma@eit.uni-kl.de  "QT_VARARGS.  Then runs the thread by calling QT_BLOCKI to hald the",
63512027Sjungma@eit.uni-kl.de  "main thread, a helper that saves the main thread's stack pointer,",
63612027Sjungma@eit.uni-kl.de  "a null startup function, a null user function, a cleanup function",
63712027Sjungma@eit.uni-kl.de  "that calls QT_ABORT and restarts the main thread.  Copies no user",
63812027Sjungma@eit.uni-kl.de  "parameters.",
63912027Sjungma@eit.uni-kl.de  ":: varargs start/stop = QT_BLOCKI + QT_ABORT + 6 function calls.",
64012027Sjungma@eit.uni-kl.de  NULL
64112027Sjungma@eit.uni-kl.de};
64212027Sjungma@eit.uni-kl.de
64312027Sjungma@eit.uni-kl.de/* Helper function to send control back to main.
64412027Sjungma@eit.uni-kl.de   Don't save anything. */
64512027Sjungma@eit.uni-kl.de
64612027Sjungma@eit.uni-kl.de
64712027Sjungma@eit.uni-kl.de/* Helper function for starting the varargs thread.  Save the stack
64812027Sjungma@eit.uni-kl.de   pointer of the main thread so we can get back there eventually. */
64912027Sjungma@eit.uni-kl.de
65012027Sjungma@eit.uni-kl.de
65112027Sjungma@eit.uni-kl.de/* Startup function for a varargs thread. */
65212027Sjungma@eit.uni-kl.de
65312027Sjungma@eit.uni-kl.de  static void
65412027Sjungma@eit.uni-kl.detest10_startup (void *pt)
65512027Sjungma@eit.uni-kl.de{
65612027Sjungma@eit.uni-kl.de}
65712027Sjungma@eit.uni-kl.de
65812027Sjungma@eit.uni-kl.de
65912027Sjungma@eit.uni-kl.de/* User function for a varargs thread. */
66012027Sjungma@eit.uni-kl.de
66112027Sjungma@eit.uni-kl.de  static void *
66212027Sjungma@eit.uni-kl.detest10_run (int arg0, ...)
66312027Sjungma@eit.uni-kl.de{
66412027Sjungma@eit.uni-kl.de  /* return (garbage); */
66512027Sjungma@eit.uni-kl.de}
66612027Sjungma@eit.uni-kl.de
66712027Sjungma@eit.uni-kl.de
66812027Sjungma@eit.uni-kl.de/* Cleanup function for a varargs thread.  Send control
66912027Sjungma@eit.uni-kl.de   back to the main thread.  Don't save any state from the thread that
67012027Sjungma@eit.uni-kl.de   is halting. */
67112027Sjungma@eit.uni-kl.de
67212027Sjungma@eit.uni-kl.de  void
67312027Sjungma@eit.uni-kl.detest10_cleanup (void *pt, void *vuserf_retval)
67412027Sjungma@eit.uni-kl.de{
67512027Sjungma@eit.uni-kl.de  QT_ABORT (t_null, 0, 0, ((thread_t *)pt)->qt);
67612027Sjungma@eit.uni-kl.de}
67712027Sjungma@eit.uni-kl.de
67812027Sjungma@eit.uni-kl.de
67912027Sjungma@eit.uni-kl.de  void
68012027Sjungma@eit.uni-kl.detest10_init (thread_t *new, thread_t *next, int nbytes, ...)
68112027Sjungma@eit.uni-kl.de{
68212027Sjungma@eit.uni-kl.de  va_list ap;
68312027Sjungma@eit.uni-kl.de
68412027Sjungma@eit.uni-kl.de  va_start (ap, nbytes);
68512027Sjungma@eit.uni-kl.de  new->qt = QT_VARGS (new->top, nbytes, ap, next, test10_startup,
68612027Sjungma@eit.uni-kl.de		      test10_run, test10_cleanup);
68712027Sjungma@eit.uni-kl.de  va_end (ap);
68812027Sjungma@eit.uni-kl.de}
68912027Sjungma@eit.uni-kl.de
69012027Sjungma@eit.uni-kl.de
69112027Sjungma@eit.uni-kl.de  void
69212027Sjungma@eit.uni-kl.detest10 (int n)
69312027Sjungma@eit.uni-kl.de{
69412027Sjungma@eit.uni-kl.de  thread_t main;
69512027Sjungma@eit.uni-kl.de  thread_t *t;
69612027Sjungma@eit.uni-kl.de
69712027Sjungma@eit.uni-kl.de  t = t_alloc();
69812027Sjungma@eit.uni-kl.de  t->next = &main;
69912027Sjungma@eit.uni-kl.de
70012027Sjungma@eit.uni-kl.de  while (--n >= 0) {
70112027Sjungma@eit.uni-kl.de    test10_init (t, &main, 0);
70212027Sjungma@eit.uni-kl.de    QT_BLOCKI (t_splat, &main.qt, 0, t->qt);
70312027Sjungma@eit.uni-kl.de  }
70412027Sjungma@eit.uni-kl.de  t_free (t);
70512027Sjungma@eit.uni-kl.de}
70612027Sjungma@eit.uni-kl.de
70712027Sjungma@eit.uni-kl.de
70812027Sjungma@eit.uni-kl.dechar const test11_msg[] = { "*Test varargs init & startup w/ 2 args." };
70912027Sjungma@eit.uni-kl.de
71012027Sjungma@eit.uni-kl.dechar const *test11_descr[] = {
71112027Sjungma@eit.uni-kl.de  "Varargs initialization/run.  Copies 2 user arguments.",
71212027Sjungma@eit.uni-kl.de  ":: varargs 2 start/stop = QT_VARGS(2 args), QT_BLOCKI, QT_ABORT, 6 f() calls.",
71312027Sjungma@eit.uni-kl.de  NULL
71412027Sjungma@eit.uni-kl.de};
71512027Sjungma@eit.uni-kl.de
71612027Sjungma@eit.uni-kl.de
71712027Sjungma@eit.uni-kl.de  void
71812027Sjungma@eit.uni-kl.detest11 (int n)
71912027Sjungma@eit.uni-kl.de{
72012027Sjungma@eit.uni-kl.de  thread_t main;
72112027Sjungma@eit.uni-kl.de  thread_t *t;
72212027Sjungma@eit.uni-kl.de
72312027Sjungma@eit.uni-kl.de  t = t_alloc();
72412027Sjungma@eit.uni-kl.de  t->next = &main;
72512027Sjungma@eit.uni-kl.de
72612027Sjungma@eit.uni-kl.de  while (--n >= 0) {
72712027Sjungma@eit.uni-kl.de    test10_init (t, &main, 2 * sizeof(int), 2, 1);
72812027Sjungma@eit.uni-kl.de    QT_BLOCKI (t_splat, &main.qt, 0, t->qt);
72912027Sjungma@eit.uni-kl.de  }
73012027Sjungma@eit.uni-kl.de  t_free (t);
73112027Sjungma@eit.uni-kl.de}
73212027Sjungma@eit.uni-kl.de
73312027Sjungma@eit.uni-kl.dechar const test12_msg[] = { "*Test varargs init & startup w/ 4 args." };
73412027Sjungma@eit.uni-kl.de
73512027Sjungma@eit.uni-kl.dechar const *test12_descr[] = {
73612027Sjungma@eit.uni-kl.de  "Varargs initialization/run.  Copies 4 user arguments.",
73712027Sjungma@eit.uni-kl.de  ":: varargs 4 start/stop = QT_VARGS(4 args), QT_BLOCKI, QT_ABORT, 6 f() calls.",
73812027Sjungma@eit.uni-kl.de  NULL
73912027Sjungma@eit.uni-kl.de};
74012027Sjungma@eit.uni-kl.de
74112027Sjungma@eit.uni-kl.de
74212027Sjungma@eit.uni-kl.de  void
74312027Sjungma@eit.uni-kl.detest12 (int n)
74412027Sjungma@eit.uni-kl.de{
74512027Sjungma@eit.uni-kl.de  thread_t main;
74612027Sjungma@eit.uni-kl.de  thread_t *t;
74712027Sjungma@eit.uni-kl.de
74812027Sjungma@eit.uni-kl.de  t = t_alloc();
74912027Sjungma@eit.uni-kl.de  t->next = &main;
75012027Sjungma@eit.uni-kl.de
75112027Sjungma@eit.uni-kl.de  while (--n >= 0) {
75212027Sjungma@eit.uni-kl.de    test10_init (t, &main, 4 * sizeof(int), 4, 3, 2, 1);
75312027Sjungma@eit.uni-kl.de    QT_BLOCKI (t_splat, &main.qt, 0, t->qt);
75412027Sjungma@eit.uni-kl.de  }
75512027Sjungma@eit.uni-kl.de  t_free (t);
75612027Sjungma@eit.uni-kl.de}
75712027Sjungma@eit.uni-kl.de
75812027Sjungma@eit.uni-kl.de
75912027Sjungma@eit.uni-kl.dechar const test13_msg[] = { "*Test varargs init & startup w/ 8 args." };
76012027Sjungma@eit.uni-kl.de
76112027Sjungma@eit.uni-kl.dechar const *test13_descr[] = {
76212027Sjungma@eit.uni-kl.de  "Varargs initialization/run.  Copies 8 user arguments.",
76312027Sjungma@eit.uni-kl.de  ":: varargs 8 start/stop = QT_VARGS(8 args), QT_BLOCKI, QT_ABORT, 6 f() calls.",
76412027Sjungma@eit.uni-kl.de  NULL
76512027Sjungma@eit.uni-kl.de};
76612027Sjungma@eit.uni-kl.de
76712027Sjungma@eit.uni-kl.de  void
76812027Sjungma@eit.uni-kl.detest13 (int n)
76912027Sjungma@eit.uni-kl.de{
77012027Sjungma@eit.uni-kl.de  thread_t main;
77112027Sjungma@eit.uni-kl.de  thread_t *t;
77212027Sjungma@eit.uni-kl.de
77312027Sjungma@eit.uni-kl.de  t = t_alloc();
77412027Sjungma@eit.uni-kl.de  t->next = &main;
77512027Sjungma@eit.uni-kl.de
77612027Sjungma@eit.uni-kl.de  while (--n >= 0) {
77712027Sjungma@eit.uni-kl.de    test10_init (t, &main, 8 * sizeof(int), 8, 7, 6, 5, 4, 3, 2, 1);
77812027Sjungma@eit.uni-kl.de    QT_BLOCKI (t_splat, &main.qt, 0, t->qt);
77912027Sjungma@eit.uni-kl.de  }
78012027Sjungma@eit.uni-kl.de  t_free (t);
78112027Sjungma@eit.uni-kl.de}
78212027Sjungma@eit.uni-kl.de
78312027Sjungma@eit.uni-kl.de
78412027Sjungma@eit.uni-kl.dechar const test14_msg[] = { "*Test varargs initialization w/ 0 args." };
78512027Sjungma@eit.uni-kl.de
78612027Sjungma@eit.uni-kl.dechar const *test14_descr[] = {
78712027Sjungma@eit.uni-kl.de  "Varargs initialization without running the thread.  Just calls",
78812027Sjungma@eit.uni-kl.de  "QT_VARGS.",
78912027Sjungma@eit.uni-kl.de  ":: varargs 0 init = QT_VARGS()",
79012027Sjungma@eit.uni-kl.de  NULL
79112027Sjungma@eit.uni-kl.de};
79212027Sjungma@eit.uni-kl.de
79312027Sjungma@eit.uni-kl.de  void
79412027Sjungma@eit.uni-kl.detest14 (int n)
79512027Sjungma@eit.uni-kl.de{
79612027Sjungma@eit.uni-kl.de  thread_t main;
79712027Sjungma@eit.uni-kl.de  thread_t *t;
79812027Sjungma@eit.uni-kl.de
79912027Sjungma@eit.uni-kl.de  t = t_alloc();
80012027Sjungma@eit.uni-kl.de  t->next = &main;
80112027Sjungma@eit.uni-kl.de
80212027Sjungma@eit.uni-kl.de  while (--n >= 0) {
80312027Sjungma@eit.uni-kl.de    test10_init (t, &main, 0 * sizeof(int));
80412027Sjungma@eit.uni-kl.de  }
80512027Sjungma@eit.uni-kl.de  t_free (t);
80612027Sjungma@eit.uni-kl.de}
80712027Sjungma@eit.uni-kl.de
80812027Sjungma@eit.uni-kl.de
80912027Sjungma@eit.uni-kl.dechar const test15_msg[] = { "*Test varargs initialization w/ 2 args." };
81012027Sjungma@eit.uni-kl.de
81112027Sjungma@eit.uni-kl.dechar const *test15_descr[] = {
81212027Sjungma@eit.uni-kl.de  "Varargs initialization without running the thread.  Just calls",
81312027Sjungma@eit.uni-kl.de  "QT_VARGS.",
81412027Sjungma@eit.uni-kl.de  ":: varargs 2 init = QT_VARGS(2 args)",
81512027Sjungma@eit.uni-kl.de  NULL
81612027Sjungma@eit.uni-kl.de};
81712027Sjungma@eit.uni-kl.de
81812027Sjungma@eit.uni-kl.de  void
81912027Sjungma@eit.uni-kl.detest15 (int n)
82012027Sjungma@eit.uni-kl.de{
82112027Sjungma@eit.uni-kl.de  thread_t main;
82212027Sjungma@eit.uni-kl.de  thread_t *t;
82312027Sjungma@eit.uni-kl.de
82412027Sjungma@eit.uni-kl.de  t = t_alloc();
82512027Sjungma@eit.uni-kl.de  t->next = &main;
82612027Sjungma@eit.uni-kl.de
82712027Sjungma@eit.uni-kl.de  while (--n >= 0) {
82812027Sjungma@eit.uni-kl.de    test10_init (t, &main, 2 * sizeof(int), 2, 1);
82912027Sjungma@eit.uni-kl.de  }
83012027Sjungma@eit.uni-kl.de  t_free (t);
83112027Sjungma@eit.uni-kl.de}
83212027Sjungma@eit.uni-kl.de
83312027Sjungma@eit.uni-kl.dechar const test16_msg[] = { "*Test varargs initialization w/ 4 args." };
83412027Sjungma@eit.uni-kl.de
83512027Sjungma@eit.uni-kl.dechar const *test16_descr[] = {
83612027Sjungma@eit.uni-kl.de  "Varargs initialization without running the thread.  Just calls",
83712027Sjungma@eit.uni-kl.de  "QT_VARGS.",
83812027Sjungma@eit.uni-kl.de  ":: varargs 4 init = QT_VARGS(4 args)",
83912027Sjungma@eit.uni-kl.de  NULL
84012027Sjungma@eit.uni-kl.de};
84112027Sjungma@eit.uni-kl.de
84212027Sjungma@eit.uni-kl.de
84312027Sjungma@eit.uni-kl.de  void
84412027Sjungma@eit.uni-kl.detest16 (int n)
84512027Sjungma@eit.uni-kl.de{
84612027Sjungma@eit.uni-kl.de  thread_t main;
84712027Sjungma@eit.uni-kl.de  thread_t *t;
84812027Sjungma@eit.uni-kl.de
84912027Sjungma@eit.uni-kl.de  t = t_alloc();
85012027Sjungma@eit.uni-kl.de  t->next = &main;
85112027Sjungma@eit.uni-kl.de
85212027Sjungma@eit.uni-kl.de  while (--n >= 0) {
85312027Sjungma@eit.uni-kl.de    test10_init (t, &main, 4 * sizeof(int), 4, 3, 2, 1);
85412027Sjungma@eit.uni-kl.de  }
85512027Sjungma@eit.uni-kl.de  t_free (t);
85612027Sjungma@eit.uni-kl.de}
85712027Sjungma@eit.uni-kl.de
85812027Sjungma@eit.uni-kl.de
85912027Sjungma@eit.uni-kl.dechar const test17_msg[] = { "*Test varargs initialization w/ 8 args." };
86012027Sjungma@eit.uni-kl.de
86112027Sjungma@eit.uni-kl.dechar const *test17_descr[] = {
86212027Sjungma@eit.uni-kl.de  "Varargs initialization without running the thread.  Just calls",
86312027Sjungma@eit.uni-kl.de  "QT_VARGS.",
86412027Sjungma@eit.uni-kl.de  ":: varargs 8 init = QT_VARGS(8 args)",
86512027Sjungma@eit.uni-kl.de  NULL
86612027Sjungma@eit.uni-kl.de};
86712027Sjungma@eit.uni-kl.de
86812027Sjungma@eit.uni-kl.de
86912027Sjungma@eit.uni-kl.de  void
87012027Sjungma@eit.uni-kl.detest17 (int n)
87112027Sjungma@eit.uni-kl.de{
87212027Sjungma@eit.uni-kl.de  thread_t main;
87312027Sjungma@eit.uni-kl.de  thread_t *t;
87412027Sjungma@eit.uni-kl.de
87512027Sjungma@eit.uni-kl.de  t = t_alloc();
87612027Sjungma@eit.uni-kl.de  t->next = &main;
87712027Sjungma@eit.uni-kl.de
87812027Sjungma@eit.uni-kl.de  while (--n >= 0) {
87912027Sjungma@eit.uni-kl.de    test10_init (t, &main, 8 * sizeof(int), 8, 7, 6, 5, 4, 3, 2, 1);
88012027Sjungma@eit.uni-kl.de  }
88112027Sjungma@eit.uni-kl.de  t_free (t);
88212027Sjungma@eit.uni-kl.de}
88312027Sjungma@eit.uni-kl.de
88412027Sjungma@eit.uni-kl.de/* Test times for basic machine operations. */
88512027Sjungma@eit.uni-kl.de
88612027Sjungma@eit.uni-kl.dechar const test18_msg[] = { "*Call register indirect." };
88712027Sjungma@eit.uni-kl.dechar const *test18_descr[] = { NULL };
88812027Sjungma@eit.uni-kl.de
88912027Sjungma@eit.uni-kl.de  void
89012027Sjungma@eit.uni-kl.detest18 (int n)
89112027Sjungma@eit.uni-kl.de{
89212027Sjungma@eit.uni-kl.de  b_call_reg (n);
89312027Sjungma@eit.uni-kl.de}
89412027Sjungma@eit.uni-kl.de
89512027Sjungma@eit.uni-kl.de
89612027Sjungma@eit.uni-kl.dechar const test19_msg[] = { "*Call immediate." };
89712027Sjungma@eit.uni-kl.dechar const *test19_descr[] = { NULL };
89812027Sjungma@eit.uni-kl.de
89912027Sjungma@eit.uni-kl.de  void
90012027Sjungma@eit.uni-kl.detest19 (int n)
90112027Sjungma@eit.uni-kl.de{
90212027Sjungma@eit.uni-kl.de  b_call_imm (n);
90312027Sjungma@eit.uni-kl.de}
90412027Sjungma@eit.uni-kl.de
90512027Sjungma@eit.uni-kl.de
90612027Sjungma@eit.uni-kl.dechar const test20_msg[] = { "*Add register-to-register." };
90712027Sjungma@eit.uni-kl.dechar const *test20_descr[] = { NULL };
90812027Sjungma@eit.uni-kl.de
90912027Sjungma@eit.uni-kl.de  void
91012027Sjungma@eit.uni-kl.detest20 (int n)
91112027Sjungma@eit.uni-kl.de{
91212027Sjungma@eit.uni-kl.de  b_add (n);
91312027Sjungma@eit.uni-kl.de}
91412027Sjungma@eit.uni-kl.de
91512027Sjungma@eit.uni-kl.de
91612027Sjungma@eit.uni-kl.dechar const test21_msg[] = { "*Load memory to a register." };
91712027Sjungma@eit.uni-kl.dechar const *test21_descr[] = { NULL };
91812027Sjungma@eit.uni-kl.de
91912027Sjungma@eit.uni-kl.de  void
92012027Sjungma@eit.uni-kl.detest21 (int n)
92112027Sjungma@eit.uni-kl.de{
92212027Sjungma@eit.uni-kl.de  b_load (n);
92312027Sjungma@eit.uni-kl.de}
92412027Sjungma@eit.uni-kl.de
92512027Sjungma@eit.uni-kl.de/* Driver. */
92612027Sjungma@eit.uni-kl.de
92712027Sjungma@eit.uni-kl.detypedef struct foo_t {
92812027Sjungma@eit.uni-kl.de    char const *msg;	/* Message to print for generic help. */
92912027Sjungma@eit.uni-kl.de    char const **descr;	/* A description of what is done by the test. */
93012027Sjungma@eit.uni-kl.de    void (*f)(int n);
93112027Sjungma@eit.uni-kl.de} foo_t;
93212027Sjungma@eit.uni-kl.de
93312027Sjungma@eit.uni-kl.de
93412027Sjungma@eit.uni-kl.destatic foo_t foo[] = {
93512027Sjungma@eit.uni-kl.de  { "Usage:\n", NULL, (void(*)(int n))usage },
93612027Sjungma@eit.uni-kl.de  { test01_msg, test01_descr, test01 },
93712027Sjungma@eit.uni-kl.de  { test02_msg, NULL, test02 },
93812027Sjungma@eit.uni-kl.de  { test03_msg, NULL, test03 },
93912027Sjungma@eit.uni-kl.de  { test04_msg, NULL, test04 },
94012027Sjungma@eit.uni-kl.de  { test05_msg, NULL, test05 },
94112027Sjungma@eit.uni-kl.de  { test06_msg, test06_descr, test06 },
94212027Sjungma@eit.uni-kl.de  { test07_msg, test07_descr, test07 },
94312027Sjungma@eit.uni-kl.de  { test08_msg, test08_descr, test08 },
94412027Sjungma@eit.uni-kl.de  { test09_msg, NULL, test09 },
94512027Sjungma@eit.uni-kl.de  { test10_msg, test10_descr, test10 },
94612027Sjungma@eit.uni-kl.de  { test11_msg, test11_descr, test11 },
94712027Sjungma@eit.uni-kl.de  { test12_msg, test12_descr, test12 },
94812027Sjungma@eit.uni-kl.de  { test13_msg, test13_descr, test13 },
94912027Sjungma@eit.uni-kl.de  { test14_msg, test14_descr, test14 },
95012027Sjungma@eit.uni-kl.de  { test15_msg, test15_descr, test15 },
95112027Sjungma@eit.uni-kl.de  { test16_msg, test16_descr, test16 },
95212027Sjungma@eit.uni-kl.de  { test17_msg, test17_descr, test17 },
95312027Sjungma@eit.uni-kl.de  { test18_msg, test18_descr, test18 },
95412027Sjungma@eit.uni-kl.de  { test19_msg, test19_descr, test19 },
95512027Sjungma@eit.uni-kl.de  { test20_msg, test20_descr, test20 },
95612027Sjungma@eit.uni-kl.de  { test21_msg, test21_descr, test21 },
95712027Sjungma@eit.uni-kl.de  { 0, 0 }
95812027Sjungma@eit.uni-kl.de};
95912027Sjungma@eit.uni-kl.de
96012027Sjungma@eit.uni-kl.destatic int tv = 0;
96112027Sjungma@eit.uni-kl.de
96212027Sjungma@eit.uni-kl.de  void
96312027Sjungma@eit.uni-kl.detracer ()
96412027Sjungma@eit.uni-kl.de{
96512027Sjungma@eit.uni-kl.de
96612027Sjungma@eit.uni-kl.de  fprintf (stderr, "tracer\t%d\n", tv++);
96712027Sjungma@eit.uni-kl.de  fflush (stderr);
96812027Sjungma@eit.uni-kl.de}
96912027Sjungma@eit.uni-kl.de
97012027Sjungma@eit.uni-kl.de  void
97112027Sjungma@eit.uni-kl.detracer2 (void *val)
97212027Sjungma@eit.uni-kl.de{
97312027Sjungma@eit.uni-kl.de  fprintf (stderr, "tracer2\t%d val=0x%p", tv++, val);
97412027Sjungma@eit.uni-kl.de  fflush (stderr);
97512027Sjungma@eit.uni-kl.de}
97612027Sjungma@eit.uni-kl.de
97712027Sjungma@eit.uni-kl.de
97812027Sjungma@eit.uni-kl.de  void
97912027Sjungma@eit.uni-kl.dedescribe()
98012027Sjungma@eit.uni-kl.de{
98112027Sjungma@eit.uni-kl.de  int i;
98212027Sjungma@eit.uni-kl.de  FILE *out = stdout;
98312027Sjungma@eit.uni-kl.de
98412027Sjungma@eit.uni-kl.de  for (i=0; foo[i].msg; ++i) {
98512027Sjungma@eit.uni-kl.de    if (foo[i].descr) {
98612027Sjungma@eit.uni-kl.de      int j;
98712027Sjungma@eit.uni-kl.de
98812027Sjungma@eit.uni-kl.de      putc ('\n', out);
98912027Sjungma@eit.uni-kl.de      fprintf (out, "[%d]\n", i);
99012027Sjungma@eit.uni-kl.de      for (j=0; foo[i].descr[j]; ++j) {
99112027Sjungma@eit.uni-kl.de	fputs (foo[i].descr[j], out);
99212027Sjungma@eit.uni-kl.de	putc ('\n', out);
99312027Sjungma@eit.uni-kl.de      }
99412027Sjungma@eit.uni-kl.de    }
99512027Sjungma@eit.uni-kl.de  }
99612027Sjungma@eit.uni-kl.de  exit (0);
99712027Sjungma@eit.uni-kl.de}
99812027Sjungma@eit.uni-kl.de
99912027Sjungma@eit.uni-kl.de
100012027Sjungma@eit.uni-kl.de  void
100112027Sjungma@eit.uni-kl.deusage()
100212027Sjungma@eit.uni-kl.de{
100312027Sjungma@eit.uni-kl.de  int i;
100412027Sjungma@eit.uni-kl.de
100512027Sjungma@eit.uni-kl.de  fputs (foo[0].msg, stderr);
100612027Sjungma@eit.uni-kl.de  for (i=1; foo[i].msg; ++i) {
100712027Sjungma@eit.uni-kl.de    fprintf (stderr, "%2d\t%s\n", i, foo[i].msg);
100812027Sjungma@eit.uni-kl.de  }
100912027Sjungma@eit.uni-kl.de  exit (1);
101012027Sjungma@eit.uni-kl.de}
101112027Sjungma@eit.uni-kl.de
101212027Sjungma@eit.uni-kl.de
101312027Sjungma@eit.uni-kl.de  void
101412027Sjungma@eit.uni-kl.deargs (int *which, int *n, int argc, char **argv)
101512027Sjungma@eit.uni-kl.de{
101612027Sjungma@eit.uni-kl.de  static int nfuncs = 0;
101712027Sjungma@eit.uni-kl.de
101812027Sjungma@eit.uni-kl.de  if (argc == 2 && argv[1][0] == '-' && argv[1][1] == 'h') {
101912027Sjungma@eit.uni-kl.de    describe();
102012027Sjungma@eit.uni-kl.de  }
102112027Sjungma@eit.uni-kl.de
102212027Sjungma@eit.uni-kl.de  if (nfuncs == 0) {
102312027Sjungma@eit.uni-kl.de    for (nfuncs=0; foo[nfuncs].msg; ++nfuncs)
102412027Sjungma@eit.uni-kl.de      ;
102512027Sjungma@eit.uni-kl.de  }
102612027Sjungma@eit.uni-kl.de
102712027Sjungma@eit.uni-kl.de  if (argc != 2 && argc != 3) {
102812027Sjungma@eit.uni-kl.de    usage();
102912027Sjungma@eit.uni-kl.de  }
103012027Sjungma@eit.uni-kl.de
103112027Sjungma@eit.uni-kl.de  *which = atoi (argv[1]);
103212027Sjungma@eit.uni-kl.de  if (*which < 0 || *which >= nfuncs) {
103312027Sjungma@eit.uni-kl.de    usage();
103412027Sjungma@eit.uni-kl.de  }
103512027Sjungma@eit.uni-kl.de  *n = (argc == 3)
103612027Sjungma@eit.uni-kl.de    ? atoi (argv[2])
103712027Sjungma@eit.uni-kl.de    : 1;
103812027Sjungma@eit.uni-kl.de}
103912027Sjungma@eit.uni-kl.de
104012027Sjungma@eit.uni-kl.de
104112027Sjungma@eit.uni-kl.de  int
104212027Sjungma@eit.uni-kl.demain (int argc, char **argv)
104312027Sjungma@eit.uni-kl.de{
104412027Sjungma@eit.uni-kl.de  int which, n;
104512027Sjungma@eit.uni-kl.de  args (&which, &n, argc, argv);
104612027Sjungma@eit.uni-kl.de  (*(foo[which].f))(n);
104712027Sjungma@eit.uni-kl.de  exit (0);
104812027Sjungma@eit.uni-kl.de  return (0);
104912027Sjungma@eit.uni-kl.de}
1050