blob: b7950c985fbbc9d9c3912ce9fdf7c8b912d34fec [file] [log] [blame]
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "dreadthread.h"
#define NTHREADS 1000
#define STACKSIZE (8 * 1024)
#define COUNT 100
int count = COUNT;
int nthreads = NTHREADS;
int stacksize = STACKSIZE;
int all_at_once = 0;
int all_go = 0;
struct dthr_event go_eva;
struct dthr_semaphore go_sema;
struct thread_specifics {
int thread_num;
int counter;
double val;
};
void *myThread(void *arg)
{
int index = (uintptr_t) arg;
struct thread_specifics *info;
int th_num;
double v;
if (all_at_once) {
dthr_semaphore_take(&go_sema);
while (!all_go) {
dthr_event_wait(&go_eva,&go_sema);
}
dthr_semaphore_drop(&go_sema);
}
info = (struct thread_specifics *) dthr_cur_thread->data;
th_num = info->thread_num;
if (index != th_num) {
fprintf(stderr,"Thread %d: arg %d != thread data\n",th_num,index);
}
v = info->val;
while (info->counter < count) {
dthr_thread_yield();
printf("Thread %d: count %d, val-1.0=%g\n",th_num,info->counter,v-1.0);
v = sqrt(v);
info->counter++;
}
return 0;
}
struct dthr_thread *th, main_th;
struct thread_specifics *priv;
void *goForIt(void *unused)
{
int i;
if (all_at_once) {
dthr_semaphore_init(&go_sema,1);
dthr_event_init(&go_eva);
}
for (i = 0; i < nthreads; i++)
(void) dthr_thread_detach(dthr_thread_run(&th[i]));
(void) dthr_thread_detach(dthr_cur_thread);
if (all_at_once) {
dthr_semaphore_take(&go_sema);
all_go = 1;
dthr_semaphore_drop(&go_sema);
dthr_event_broadcast(&go_eva);
}
return 0;
}
extern int getopt();
extern char *optarg, *rindex();
char *me;
void usage()
{
fprintf(stderr,
"Usage: %s [-aA] [-s stackbytes] [-c count] [-t nthreads]\n",
me);
}
int main(int ac, char **av)
{
int opt;
int i;
if (!(me = strrchr(*av,'/'))) me = *av;
else ++me;
while ((opt = getopt(ac,av,"aAc:s:t:")) != EOF) switch (opt) {
case 'a': all_at_once = 1; break;
case 'A': all_at_once = 0; break;
case 'c': count = atoi(optarg); break;
case 's': stacksize = atoi(optarg); break;
case 't': nthreads = atoi(optarg); break;
default: usage(); exit(1);
}
th = (struct dthr_thread *) malloc(nthreads * sizeof *th);
if (!th) {
perror(me);
fprintf(stderr,"%s: insufficient space for thread descriptors\n", me);
exit(1);
}
priv = (struct thread_specifics *) malloc(nthreads * sizeof *priv);
if (!priv) {
perror(me);
fprintf(stderr,"%s: insufficient space for thread private data\n", me);
exit(1);
}
dthr_init();
for (i = 0; i < nthreads; i++) {
(void) dthr_thread_init(&th[i],myThread,(void *) (uintptr_t) i,stacksize);
th[i].data = (void *) &priv[i];
priv[i].thread_num = i;
priv[i].counter = 0;
priv[i].val = 100.0 * i;
}
printf("main: dthr_thread_init (main thread)\n");
dthr_thread_init(&main_th, goForIt, (void *) 0, stacksize);
printf("main: dthr_thread_multithread ***\n");
dthr_thread_multithread(&main_th);
fprintf(stderr,"All threads exited, all done!\n");
return 0;
}