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

📄 meas.c

📁 system C源码 一种替代verilog的语言
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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 voidt_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 voidtest01 (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 voidtest02_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 voidtest02 (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 voidtest03_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 voidtest03 (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 voidtest04 (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 voidtest05_aux (void *null){  stp_yield();  stp_yield();}  static voidtest05 (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 voidtest06_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 voidtest06 (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 voidtest07_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 voidtest07_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 voidtest07 (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 voidtest08_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 voidtest08_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 voidtest08 (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;

⌨️ 快捷键说明

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