From 798f40001b65e7625e99265423cb6d7863aba8e4 Mon Sep 17 00:00:00 2001 From: phk Date: Fri, 13 Sep 2002 13:13:00 +0000 Subject: Overhaul the kernel-simulation bits here to use pthreads instead. If somebody wanted to, this could for the beginning of a "libkernel" which could be used to run kernel code in userland. Sponsored by: DARPA & NAI Labs. --- tools/regression/geom/Test/Makefile.inc | 2 +- tools/regression/geom/Test/T000/testprg.c | 2 +- tools/regression/geom/Test/T001/testprg.c | 2 +- tools/regression/geom/Test/T002/testprg.c | 2 +- tools/regression/geom/Test/T003/testprg.c | 2 +- tools/regression/geom/Test/T004/testprg.c | 2 +- tools/regression/geom/Test/T005/testprg.c | 2 +- tools/regression/geom/Test/T006/testprg.c | 2 +- tools/regression/geom/Test/T007/testprg.c | 2 +- tools/regression/geom/Test/T008/testprg.c | 2 +- tools/regression/geom/Test/T009/testprg.c | 2 +- tools/regression/geom/Test/T010/testprg.c | 2 +- tools/regression/geom/Test/T011/testprg.c | 2 +- tools/regression/geom/Test/T012/testprg.c | 2 +- tools/regression/geom/Test/T013/testprg.c | 2 +- tools/regression/geom/Test/T014/testprg.c | 2 +- tools/regression/geom/geom.c | 50 ++++++-- tools/regression/geom/geom_kernsim.c | 197 +++++++++++------------------- tools/regression/geom/geom_sim.h | 25 ++-- 19 files changed, 144 insertions(+), 160 deletions(-) (limited to 'tools/regression/geom') diff --git a/tools/regression/geom/Test/Makefile.inc b/tools/regression/geom/Test/Makefile.inc index 9e43900..c53257e 100644 --- a/tools/regression/geom/Test/Makefile.inc +++ b/tools/regression/geom/Test/Makefile.inc @@ -5,7 +5,7 @@ NOMAN = no NOOBJ = youbet CFLAGS += -g -W -Wall -Wstrict-prototypes -Wmissing-prototypes CFLAGS += -Wpointer-arith -static -I/usr/src/sys -I../.. -CFLAGS += -DKERNELSIM +CFLAGS += -DKERNELSIM -pthread LDADD += -L../../GLib -lG LDADD += -L/usr/local/lib -lexpat DPADD += ../../GLib/libG.a diff --git a/tools/regression/geom/Test/T000/testprg.c b/tools/regression/geom/Test/T000/testprg.c index fe28455..eb53a9c 100644 --- a/tools/regression/geom/Test/T000/testprg.c +++ b/tools/regression/geom/Test/T000/testprg.c @@ -47,7 +47,7 @@ #include #include -int +void * thread_sim(void *ptr __unused) { diff --git a/tools/regression/geom/Test/T001/testprg.c b/tools/regression/geom/Test/T001/testprg.c index 1c7865a..263665e 100644 --- a/tools/regression/geom/Test/T001/testprg.c +++ b/tools/regression/geom/Test/T001/testprg.c @@ -47,7 +47,7 @@ #include #include -int +void * thread_sim(void *ptr __unused) { diff --git a/tools/regression/geom/Test/T002/testprg.c b/tools/regression/geom/Test/T002/testprg.c index 7ffcd68..d7e6181 100644 --- a/tools/regression/geom/Test/T002/testprg.c +++ b/tools/regression/geom/Test/T002/testprg.c @@ -47,7 +47,7 @@ #include #include -int +void * thread_sim(void *ptr __unused) { diff --git a/tools/regression/geom/Test/T003/testprg.c b/tools/regression/geom/Test/T003/testprg.c index 70631ef..3acfcec 100644 --- a/tools/regression/geom/Test/T003/testprg.c +++ b/tools/regression/geom/Test/T003/testprg.c @@ -47,7 +47,7 @@ #include #include -int +void * thread_sim(void *ptr __unused) { diff --git a/tools/regression/geom/Test/T004/testprg.c b/tools/regression/geom/Test/T004/testprg.c index 705f6ed..2c0dcd2 100644 --- a/tools/regression/geom/Test/T004/testprg.c +++ b/tools/regression/geom/Test/T004/testprg.c @@ -47,7 +47,7 @@ #include #include -int +void * thread_sim(void *ptr __unused) { diff --git a/tools/regression/geom/Test/T005/testprg.c b/tools/regression/geom/Test/T005/testprg.c index 119b3ed..af1d3f7 100644 --- a/tools/regression/geom/Test/T005/testprg.c +++ b/tools/regression/geom/Test/T005/testprg.c @@ -47,7 +47,7 @@ #include #include -int +void * thread_sim(void *ptr __unused) { diff --git a/tools/regression/geom/Test/T006/testprg.c b/tools/regression/geom/Test/T006/testprg.c index 10296af..57c9522 100644 --- a/tools/regression/geom/Test/T006/testprg.c +++ b/tools/regression/geom/Test/T006/testprg.c @@ -47,7 +47,7 @@ #include #include -int +void * thread_sim(void *ptr __unused) { diff --git a/tools/regression/geom/Test/T007/testprg.c b/tools/regression/geom/Test/T007/testprg.c index e07f87e..bc302be 100644 --- a/tools/regression/geom/Test/T007/testprg.c +++ b/tools/regression/geom/Test/T007/testprg.c @@ -47,7 +47,7 @@ #include #include -int +void * thread_sim(void *ptr __unused) { diff --git a/tools/regression/geom/Test/T008/testprg.c b/tools/regression/geom/Test/T008/testprg.c index 21d960b..eca224a 100644 --- a/tools/regression/geom/Test/T008/testprg.c +++ b/tools/regression/geom/Test/T008/testprg.c @@ -47,7 +47,7 @@ #include #include -int +void * thread_sim(void *ptr __unused) { struct g_consumer *cp; diff --git a/tools/regression/geom/Test/T009/testprg.c b/tools/regression/geom/Test/T009/testprg.c index 3b2bfaf..ab71e92 100644 --- a/tools/regression/geom/Test/T009/testprg.c +++ b/tools/regression/geom/Test/T009/testprg.c @@ -47,7 +47,7 @@ #include #include -int +void * thread_sim(void *ptr __unused) { struct g_consumer *cp; diff --git a/tools/regression/geom/Test/T010/testprg.c b/tools/regression/geom/Test/T010/testprg.c index 1246054..29dd6ca 100644 --- a/tools/regression/geom/Test/T010/testprg.c +++ b/tools/regression/geom/Test/T010/testprg.c @@ -47,7 +47,7 @@ #include #include -int +void * thread_sim(void *ptr __unused) { struct g_consumer *cp; diff --git a/tools/regression/geom/Test/T011/testprg.c b/tools/regression/geom/Test/T011/testprg.c index 455f6ef..44e4b69 100644 --- a/tools/regression/geom/Test/T011/testprg.c +++ b/tools/regression/geom/Test/T011/testprg.c @@ -47,7 +47,7 @@ #include #include -int +void * thread_sim(void *ptr __unused) { struct g_consumer *cp; diff --git a/tools/regression/geom/Test/T012/testprg.c b/tools/regression/geom/Test/T012/testprg.c index 0b9453d..28645d7 100644 --- a/tools/regression/geom/Test/T012/testprg.c +++ b/tools/regression/geom/Test/T012/testprg.c @@ -47,7 +47,7 @@ #include #include -int +void * thread_sim(void *ptr __unused) { diff --git a/tools/regression/geom/Test/T013/testprg.c b/tools/regression/geom/Test/T013/testprg.c index aebd9d9..f538a30 100644 --- a/tools/regression/geom/Test/T013/testprg.c +++ b/tools/regression/geom/Test/T013/testprg.c @@ -47,7 +47,7 @@ #include #include -int +void * thread_sim(void *ptr __unused) { diff --git a/tools/regression/geom/Test/T014/testprg.c b/tools/regression/geom/Test/T014/testprg.c index 5eba6d4..eb76581 100644 --- a/tools/regression/geom/Test/T014/testprg.c +++ b/tools/regression/geom/Test/T014/testprg.c @@ -46,7 +46,7 @@ #include #include -int +void * thread_sim(void *ptr __unused) { diff --git a/tools/regression/geom/geom.c b/tools/regression/geom/geom.c index 1852cc4..1873e06 100644 --- a/tools/regression/geom/geom.c +++ b/tools/regression/geom/geom.c @@ -66,42 +66,70 @@ conff(char *file) free(s); } - - - -static int +static void * thread_up(void *ptr) { struct thread *tp = ptr; + int error; printf("Running %s\n", tp->name); + error = pthread_cond_init(&ptc_up, NULL); + if (error) + err(1, "pthread_cond_init(ptc_up)"); + error = pthread_mutex_init(&ptm_up, NULL); + if (error) + err(1, "pthread_mutex_init(ptm_up)"); + + error = pthread_mutex_lock(&ptm_up); + if (error) + err(1, "pthread_mutex_init(ptm_up)"); for (;;) { g_io_schedule_up(tp); - tsleep(&g_wait_up, 0, "up", 0); + error = pthread_cond_wait(&ptc_up, &ptm_up); } } -static int +static void * thread_down(void *ptr) { struct thread *tp = ptr; + int error; + printf("Running %s\n", tp->name); + error = pthread_cond_init(&ptc_down, NULL); + if (error) + err(1, "pthread_cond_init(ptc_down)"); + error = pthread_mutex_init(&ptm_down, NULL); + if (error) + err(1, "pthread_mutex_init(ptm_down)"); + error = pthread_mutex_lock(&ptm_down); + if (error) + err(1, "pthread_mutex_init(ptm_down)"); for (;;) { g_io_schedule_down(tp); - tsleep(&g_wait_down, 0, "down", 0); + error = pthread_cond_wait(&ptc_down, &ptm_down); } } -static int +static void * thread_event(void *ptr) { struct thread *tp = ptr; - /* nice(5); */ + int error; + printf("Running %s\n", tp->name); + error = pthread_cond_init(&ptc_event, NULL); + if (error) + err(1, "pthread_cond_init(ptc_event)"); + error = pthread_mutex_init(&ptm_event, NULL); + if (error) + err(1, "pthread_mutex_init(ptm_event)"); + error = pthread_mutex_lock(&ptm_event); + if (error) + err(1, "pthread_mutex_init(ptm_event)"); for (;;) { - usleep(100000); g_run_events(); - tsleep(&g_wait_event, 0, "events", 0); + error = pthread_cond_wait(&ptc_event, &ptm_event); } } diff --git a/tools/regression/geom/geom_kernsim.c b/tools/regression/geom/geom_kernsim.c index ba3ccf6..7b92578 100644 --- a/tools/regression/geom/geom_kernsim.c +++ b/tools/regression/geom/geom_kernsim.c @@ -51,6 +51,8 @@ #include #include +#include + #define NTHREAD 30 static struct thread thr[NTHREAD]; @@ -61,6 +63,8 @@ int bootverbose = 1; void done(void) { + + rattle(); weredone = 1; exit(0); } @@ -94,136 +98,108 @@ scram: exit(9); } -static int sleeping; void -wakeup(void *chan) +biodone(struct bio *bp) { - int i; + bp->bio_flags |= BIO_DONE; + if (bp->bio_done != NULL) + bp->bio_done(bp); +} - secrethandshake(); - for (i = 0; i < NTHREAD; i++) - if (thr[i].wchan == chan) { - printf("wakeup %s\n", thr[i].name); - atomic_clear_int(&sleeping, 1 << i); - write(thr[i].pipe[1], "\0", 1); - } +int +biowait(struct bio *bp, const char *wchan __unused) +{ + + while ((bp->bio_flags & BIO_DONE) == 0) + usleep(10000); + if (!(bp->bio_flags & BIO_ERROR)) + return (0); + if (bp->bio_error) + return (bp->bio_error); + return (EIO); +} + +void +wakeup(void *chan) +{ + + if (chan == &g_wait_event) + pthread_cond_signal(&ptc_event); + else if (chan == &g_wait_up) + pthread_cond_signal(&ptc_up); + else if (chan == &g_wait_down) + pthread_cond_signal(&ptc_down); + else + return; } int hz; int -tsleep(void *chan, int pri __unused, const char *wmesg, int timo) +tsleep(void *chan __unused, int pri __unused, const char *wmesg __unused, int timo) { - fd_set r,w,e; - int i, j, fd, pid; - struct timeval tv; - char buf[100]; - struct thread *tp; - secrethandshake(); - pid = getpid(); - tp = NULL; - for (i = 0; i < NTHREAD; i++) { - if (pid != thr[i].pid) - continue; - tp = &thr[i]; - break; - } - - KASSERT(tp != NULL, ("Confused tp=%p has no name\n", tp)); - KASSERT(tp->name != NULL, ("Confused tp=%p has no name\n", tp)); - tp->wchan = chan; - tp->wmesg = wmesg; - fd = tp->pipe[0]; - printf("tsleep %s %p %s\n", tp->name, chan, wmesg); - for (;;) { - if (timo > 0) { - tv.tv_sec = 1; - tv.tv_usec = 0; - } else { - tv.tv_sec = 3; - tv.tv_usec = 0; - } - FD_ZERO(&r); - FD_ZERO(&w); - FD_ZERO(&e); - FD_SET(fd, &r); - atomic_set_int(&sleeping, 1 << i); - j = select(fd + 1, &r, &w, &e, &tv); - secrethandshake(); - break; - } - if (j) - i = read(fd, buf, sizeof(buf)); - tp->wchan = 0; - tp->wmesg = 0; - return(i); + usleep(timo); + return (0); } void rattle() { - int i, j; + int i; + + pthread_yield(); for (;;) { - secrethandshake(); - usleep(500000); - secrethandshake(); - i = sleeping & 7; - if (i != 7) - continue; - usleep(20000); - j = sleeping & 7; - if (i != j) - continue; - printf("Rattle(%d) \"%s\" \"%s\" \"%s\"\n", i, thr[0].wmesg, thr[1].wmesg, thr[2].wmesg); - if (!thr[0].wmesg || strcmp(thr[0].wmesg, "up")) - continue; - if (!thr[1].wmesg || strcmp(thr[1].wmesg, "down")) - continue; - if (!thr[2].wmesg || strcmp(thr[2].wmesg, "events")) - continue; - break; + i = pthread_mutex_trylock(&ptm_up); + if (i != EBUSY) { + i = pthread_mutex_trylock(&ptm_down); + if (i != EBUSY) { + i = pthread_mutex_trylock(&ptm_event); + if (i != EBUSY) + break; + pthread_mutex_unlock(&ptm_down); + } + pthread_mutex_unlock(&ptm_up); + } + usleep(100000); } + pthread_mutex_unlock(&ptm_event); + pthread_mutex_unlock(&ptm_down); + pthread_mutex_unlock(&ptm_up); + return; } void -new_thread(int (*func)(void *arg), char *name) +new_thread(void *(*func)(void *arg), char *name) { - char *c; struct thread *tp; static int nextt; + int error; tp = thr + nextt++; - c = calloc(1, 65536); + error = pthread_create(&tp->tid, NULL, func, tp); + if (error) + err(1, "pthread_create(%s)", name); tp->name = name; - pipe(tp->pipe); - tp->pid = rfork_thread(RFPROC|RFMEM, c + 65536 - 16, func, tp); - if (tp->pid <= 0) - err(1, "rfork_thread"); printf("New Thread %d %s %p %d\n", tp - thr, name, tp, tp->pid); } #define FASCIST 0 -int malloc_lock; void * g_malloc(int size, int flags) { void *p; - secrethandshake(); - while (!atomic_cmpset_int(&malloc_lock, 0, 1)) - sched_yield(); #if FASCIST p = malloc(4096); printf("Malloc %p \n", p); #else p = malloc(size); #endif - malloc_lock = 0; if (flags & M_ZERO) memset(p, 0, size); else @@ -236,103 +212,76 @@ g_free(void *ptr) { secrethandshake(); - while (!atomic_cmpset_int(&malloc_lock, 0, 1)) - sched_yield(); #if FASCIST printf("Free %p \n", ptr); munmap(ptr, 4096); #else free(ptr); #endif - malloc_lock = 0; } +static pthread_mutex_t pt_topology; void g_init(void) { + pthread_mutex_init(&pt_topology, NULL); g_io_init(); g_event_init(); } -static int topology_lock; - void g_topology_lock() { - int pid; - pid = getpid(); - if (atomic_cmpset_int(&topology_lock, 0, pid)) - return; - KASSERT(pid != topology_lock, - ("Locking topology against myself pid %d\n", pid)); - while (!atomic_cmpset_int(&topology_lock, 0, pid)) { - printf("Waiting for topology lock mypid = %d held by %d\n", - pid, topology_lock); - sleep(1); - } + pthread_mutex_lock(&pt_topology); } void g_topology_unlock() { - KASSERT(topology_lock == getpid(), ("Didn't have topology_lock to release")); - topology_lock = 0; + pthread_mutex_unlock(&pt_topology); } void g_topology_assert() { +#if 0 if (topology_lock == getpid()) return; KASSERT(1 == 0, ("Lacking topology_lock")); -} - -void -mtx_lock_spin(struct mtx *mp) -{ - - while(!atomic_cmpset_int(&mp->mtx_lock, 0, 1)) { - printf("trying to get lock...\n"); - sched_yield(); - } -} - -void -mtx_unlock_spin(struct mtx *mp) -{ - - mp->mtx_lock = 0; +#endif } void mtx_init(struct mtx *mp, const char *bla __unused, const char *yak __unused, int foo __unused) { - mp->mtx_lock = 0; + + pthread_mutex_init((pthread_mutex_t *)&mp->mtx_object, NULL); } void mtx_destroy(struct mtx *mp) { - mp->mtx_lock = 0; + + pthread_mutex_destroy((pthread_mutex_t *)&mp->mtx_object); } void mtx_lock(struct mtx *mp) { - mp->mtx_lock = 0; + pthread_mutex_lock((pthread_mutex_t *)&mp->mtx_object); } void mtx_unlock(struct mtx *mp) { - mp->mtx_lock = 0; + pthread_mutex_unlock((pthread_mutex_t *)&mp->mtx_object); } struct mtx Giant; diff --git a/tools/regression/geom/geom_sim.h b/tools/regression/geom/geom_sim.h index df08220..6ea0470 100644 --- a/tools/regression/geom/geom_sim.h +++ b/tools/regression/geom/geom_sim.h @@ -35,19 +35,21 @@ * $FreeBSD$ */ +#include + +pthread_cond_t ptc_up, ptc_down, ptc_event; +pthread_mutex_t ptm_up, ptm_down, ptm_event; /* bio.h */ struct bio { enum { BIO_INVALID = 0, - BIO_READ, - BIO_WRITE, - BIO_FREE, - BIO_DELETE, - BIO_FORMAT, - BIO_GETATTR, - BIO_SETATTR + BIO_READ = 1, + BIO_WRITE = 2, + BIO_DELETE = 4, + BIO_GETATTR = 8, + BIO_SETATTR = 16 } bio_cmd; struct { int foo; } stats; TAILQ_ENTRY(bio) bio_queue; @@ -66,8 +68,12 @@ struct bio { struct bio *bio_linkage; int bio_flags; #define BIO_DONE 0x1 +#define BIO_ERROR 0x2 }; +void biodone(struct bio *bp); +int biowait(struct bio *bp, const char *wchan); + /* geom_dev.c */ void g_dev_init(void *junk); struct g_consumer *g_dev_opendev(char *name, int w, int r, int e); @@ -76,6 +82,7 @@ int g_dev_request(char *name, struct bio *bp); /* geom_kernsim.c */ struct thread { char *name; + pthread_t tid; int pid; void *wchan; const char *wmesg; @@ -90,7 +97,7 @@ int tsleep __P((void *chan, int pri, const char *wmesg, int timo)); #define PPAUSE 0 extern int hz; -void new_thread(int (*func)(void *arg), char *name); +void new_thread(void *(*func)(void *arg), char *name); extern int bootverbose; #define KASSERT(cond, txt) do {if (!(cond)) {printf txt; conff("err"); abort();}} while(0) @@ -139,7 +146,7 @@ void g_bsd_init(void); void g_mbr_init(void); void g_mbrext_init(void); -int thread_sim(void *ptr); +void *thread_sim(void *ptr); void dumpf(char *file); void conff(char *file); -- cgit v1.1