static void test_pc_big(void) { protothread_t const pt = protothread_create() ; int mailbox[400] ; pc_thread_context_t * const pc = malloc(sizeof(*pc) * 400) ; pc_thread_context_t * const cc = malloc(sizeof(*cc) * 400) ; int i ; /* Start 400 independent pairs of threads, each pair sharing a * mailbox. */ for (i = 0; i < 400; i++) { mailbox[i] = 0 ; cc[i].mailbox = &mailbox[i] ; cc[i].i = 0 ; pt_create(pt, &cc[i].pt_thread, consumer_thr, &cc[i]) ; pc[i].mailbox = &mailbox[i] ; pc[i].i = 0 ; pt_create(pt, &pc[i].pt_thread, producer_thr, &pc[i]) ; } /* as long as there is work to do */ while (protothread_run(pt)) ; free(cc) ; free(pc) ; protothread_free(pt) ; }
static void test_pc(void) { protothread_t const pt = protothread_create() ; pc_thread_context_t * const cc = malloc(sizeof(*cc)) ; pc_thread_context_t * const pc = malloc(sizeof(*pc)) ; int mailbox = 0 ; /* set up consumer context, start consumer thread */ cc->mailbox = &mailbox ; cc->i = 0 ; pt_create(pt, &cc->pt_thread, consumer_thr, cc) ; /* set up producer context, start producer thread */ pc->mailbox = &mailbox ; pc->i = 0 ; pt_create(pt, &pc->pt_thread, producer_thr, pc) ; /* while threads are available to run ... */ while (protothread_run(pt)) ; /* threads have completed */ assert(cc->i == N+1) ; assert(pc->i == N+1) ; free(cc) ; free(pc) ; protothread_free(pt) ; }
/* This test does not verify fairness; that's hard to do */ static void test_lock(void) { protothread_t const pt = protothread_create() ; int i ; srand(0) ; pt_lock_init(&lock_gc.lock) ; for (i = 0; i < LOCK_NTHREADS; i++) { lock_context_t * c = &lock_r_tc[i] ; c->gc = &lock_gc ; c->id = i+1 ; pt_create(pt, &c->pt_thread, read_thr, c) ; lock_gc.nthreads ++ ; } for (i = 0; i < LOCK_NTHREADS; i++) { lock_context_t * c = &lock_w_tc[i] ; c->gc = &lock_gc ; c->id = i+1 ; pt_create(pt, &c->pt_thread, write_thr, c) ; lock_gc.nthreads ++ ; } /* as long as there is work to do */ while (protothread_run(pt)) ; assert(lock_gc.nthreads == 0) ; protothread_free(pt) ; }
static pt_t recursive_thr(env_t const env) { recursive_call_context_t * const c = env ; recursive_call_global_context_t * const gc = c->gc ; pt_resume(c) ; pt_wait(c, &gc[rand() % CHANS]) ; if (c->level >= DEPTH) { /* leaf */ assert(c->value < NODES) ; assert(!gc->seen[c->value]) ; gc->seen[c->value] = TRUE ; pt_wait(c, &gc[rand() % CHANS]) ; gc->nseen ++ ; free(c) ; return PT_DONE ; } /* create the "left" (0) child; it will free this */ c->child_c = malloc(sizeof(*c->child_c)) ; *c->child_c = *c ; c->child_c->level ++ ; c->child_c->value <<= 1 ; if ((rand() % 4)) { /* usually make a synchronous function call */ pt_call(c, recursive_thr, c->child_c) ; } else { /* once in a while create a new thread (asynchronous) */ pt_create(pt_get_pt(c), &c->child_c->pt_thread, recursive_thr, c->child_c) ; } pt_wait(c, &gc[rand() % CHANS]) ; /* create the "right" (1) child; it will free this */ c->child_c = malloc(sizeof(*c->child_c)) ; *c->child_c = *c ; c->child_c->level ++ ; c->child_c->value <<= 1 ; c->child_c->value ++ ; if ((rand() % 4)) { pt_call(c, recursive_thr, c->child_c) ; } else { pt_create(pt_get_pt(c), &c->child_c->pt_thread, recursive_thr, c->child_c) ; } free(c) ; return PT_DONE ; }
static void test_recursive_once(void) { protothread_t const pt = protothread_create() ; recursive_call_global_context_t * gc = malloc(sizeof(*gc)) ; recursive_call_context_t * top_c = malloc(sizeof(*top_c)) ; int i ; memset(gc, 0, sizeof(*gc)) ; memset(top_c, 0, sizeof(*top_c)) ; top_c->gc = gc ; pt_create(pt, &top_c->pt_thread, recursive_thr, top_c) ; /* it hasn't run yet at all, make it reach the call */ i = 0 ; while (gc->nseen < NODES) { if (protothread_run(pt)) { i++ ; } /* make sure it is not taking too long (the 10 is cushion) */ assert(i < NODES*4*10) ; pt_broadcast(pt, &gc[rand() % CHANS]) ; } for (i = 0; i < NODES; i++) { assert(gc->seen[i]) ; } free(gc) ; protothread_free(pt) ; }
static void test_reset(void) { protothread_t const pt = protothread_create() ; reset_context_t * const c = calloc(1, sizeof(*c)) ; /* Start running the thread and then make sure we * can really reset the thread location */ pt_create(pt, &c->pt_thread, reset_thr, c) ; protothread_run(pt) ; assert(c->i == 0) ; protothread_run(pt) ; assert(c->i == 1) ; pt_reset(c) ; protothread_run(pt) ; assert(c->i == 0) ; while (protothread_run(pt)) ; free(c) ; protothread_free(pt) ; }
static void test_sem(void) { protothread_t const pt = protothread_create() ; sem_global_context_t * gc = malloc(sizeof(*gc)) ; int i ; gc->owner = 0 ; /* invalid ID (no one in critical section) */ /* for mutual exclusion, init the semaphore count to 1 */ gc->sem_value = 1 ; for (i = 0; i < 100; i++) { sem_context_t * const c = malloc(sizeof(*c)) ; c->gc = gc ; c->id = i+1 ; pt_create(pt, &c->pt_thread, sem_thr, c) ; } /* as long as there is work to do */ while (protothread_run(pt)) ; free(gc) ; protothread_free(pt) ; }
struct addrspace * as_create(void) { struct addrspace *as; as = kmalloc(sizeof(struct addrspace)); if (as == NULL) { return NULL; } as->as_pgtbl = pt_create(); if (as->as_pgtbl == NULL) { kfree(as); return NULL; } // Start with empty segments for (int i = 0; i < NSEGS; i++) seg_zero(&as->as_segs[i]); // set up the stack and heap to be writeable seg_init(&as->AS_STACK, 0, 0, true); seg_init(&as->AS_HEAP, 0, 0, true); as->as_loading = false; as->as_id = 0; return as; }
void menubar_create(menubar_t *m) { memset(m,0,sizeof(menubar_t)); m->info.type = G_MENUBAR; m->info.x = 0; m->info.y = 0; m->info.w = 256; m->info.h = 14; m->info.draw = (drawfunc_t)menubar_draw; m->info.event = (eventfunc_t)menubar_event; //this needs to be configurable, passed thru in a struct menu_create(&m->menus[0],"\x1",4,recentitems); menu_create(&m->menus[1],"Game",m->menus[0].info.x + m->menus[0].info.w + 4,gameitems); menu_create(&m->menus[2],"Config",m->menus[1].info.x + m->menus[1].info.w + 4,configitems); menu_create(&m->menus[3],"Cheat",m->menus[2].info.x + m->menus[2].info.w + 4,miscitems); menu_create(&m->menus[4],"Debug",m->menus[3].info.x + m->menus[3].info.w + 4,debugitems); button_create(&m->buttons[0],"x",(256 - 9) - 3,3,click_quit); button_create(&m->buttons[1],"\x9",(256 - 33) - 1,3,click_minimize); button_create(&m->buttons[2],"\x8",(256 - 21) - 3,3,click_togglefullscreen); load_create(&m->load); video_create(&m->video); input_create(&m->input); gui_input_create(&m->guiinput); sound_create(&m->sound); devices_create(&m->devices); palette_create(&m->palette); options_create(&m->options); mappers_create(&m->mappers); paths_create(&m->paths); supported_mappers_create(&m->supported_mappers); rom_info_create(&m->rom_info); tracer_create(&m->tracer); memory_viewer_create(&m->memory_viewer); nt_create(&m->nametable_viewer); pt_create(&m->patterntable_viewer); about_create(&m->about); m->menus[0].click = click_recent; m->menus[1].click = click_game; m->menus[2].click = click_config; m->menus[3].click = click_debug; m->menus[4].click = click_misc; m->menus[0].user = m; m->menus[1].user = m; m->menus[2].user = m; m->menus[3].user = m; m->menus[4].user = m; //'hack' to update the 'freeze data' caption click_freezedata(); click_freezedata(); }
static void test_wait(void) { protothread_t const pt = protothread_create() ; wait_context_t * c[10] ; int i ; int j ; for (j = 0; j < 10; j++) { c[j] = malloc(sizeof(*(c[j]))) ; c[j]->i = -1 ; pt_create(pt, &c[j]->pt_thread, wait_thr, c[j]) ; } /* threads haven't run yet at all, make them reach the wait */ for (j = 0; j < 10; j++) { protothread_run(pt) ; } for (i = 0; i < 10; i++) { for (j = 0; j < 10; j++) { assert(i == c[j]->i) ; } /* make threads runnable, but do not actually run the threads */ pt_broadcast(pt, NULL) ; for (j = 0; j < 10; j++) { assert(i == c[j]->i) ; } /* run each thread once */ for (j = 0; j < 10; j++) { protothread_run(pt) ; } for (j = 0; j < 10; j++) { assert(i+1 == c[j]->i) ; } /* extra steps and wrong signals shouldn't advance the thread */ protothread_run(pt) ; pt_broadcast(pt, c[0]) ; protothread_run(pt) ; for (j = 0; j < 10; j++) { assert(i+1 == c[j]->i) ; } } for (j = 0; j < 10; j++) { free(c[j]) ; } protothread_free(pt) ; }
static void test_thread_create(void) { protothread_t const pt = protothread_create() ; int i ; create_context_t * const c = malloc(sizeof(*c)) ; for (i = 0; i < 1000; i++) { pt_create(pt, &c->pt_thread, create_thr, c) ; protothread_run(pt) ; } free(c) ; protothread_free(pt) ; }
static void test_func_pointer(void) { protothread_t const pt = protothread_create() ; func_pointer_context_t c ; pt_f_t const func_ptr = func_pointer_thr ; /* pt_create() can take a function pointer */ c.level2.ran = FALSE ; pt_create(pt, &c.pt_thread, func_ptr, &c) ; protothread_run(pt) ; assert(!c.level2.ran) ; protothread_run(pt) ; assert(c.level2.ran) ; protothread_free(pt) ; }
int main(int argc, char *argv[]) { u_long nbufs, ptid, _ptid, n; void *buf, *lbuf; int ret; copperplate_init(argc, argv); traceobj_init(&trobj, argv[0], 0); ret = pt_create("PART", pt_mem, NULL, sizeof(pt_mem), 16, PT_NODEL, &ptid, &nbufs); traceobj_assert(&trobj, ret == SUCCESS); for (n = 0, lbuf = NULL;; n++, lbuf = buf) { ret = pt_getbuf(ptid, &buf); if (ret) { traceobj_assert(&trobj, ret == ERR_NOBUF); break; } if (lbuf) traceobj_assert(&trobj, (caddr_t)lbuf + 16 == (caddr_t)buf); memset(buf, 0xaa, 16); } traceobj_assert(&trobj, nbufs == n); ret = pt_delete(ptid); traceobj_assert(&trobj, ret == ERR_BUFINUSE); for (buf = lbuf; n > 0; n--, buf = (caddr_t)buf - 16) { ret = pt_retbuf(ptid, buf); traceobj_assert(&trobj, ret == SUCCESS); } ret = pt_ident("PART", 0, &_ptid); traceobj_assert(&trobj, ret == SUCCESS && _ptid == ptid); ret = pt_delete(ptid); traceobj_assert(&trobj, ret == SUCCESS); exit(0); }
static void test_broadcast(void) { protothread_t const pt = protothread_create() ; broadcast_global_context_t gc ; int i, j ; srand(0) ; memset(&gc, 0, sizeof(gc)) ; for (j = 0; j < N; j++) { gc.c[j].gc = &gc ; pt_create(pt, &gc.c[j].pt_thread, broadcast_thr, &gc.c[j]) ; } /* threads haven't run yet at all, make them reach the wait */ for (j = 0; j < N; j++) { protothread_run(pt) ; } for (i = 0; i < 10000; i++) { broadcast_context_t * const chan = &gc.c[(random() % N)/3] ; pt_broadcast(pt, chan) ; for (j = 0; j < N; j++) { if (gc.c[j].chan == chan) { /* should run */ gc.c[j].run = TRUE ; } } while (protothread_run(pt)) ; /* make sure every tread that should have run did run */ for (j = 0; j < N; j++) { assert(!gc.c[j].run) ; } } gc.done = TRUE ; for (j = 0; j < N; j++) { pt_broadcast(pt, &gc.c[j]) ; } while (protothread_run(pt)) ; protothread_free(pt) ; }
static void test_yield(void) { protothread_t const pt = protothread_create() ; yield_context_t * const c = malloc(sizeof(*c)) ; int i ; c->i = -1 ; /* invalid value */ pt_create(pt, &c->pt_thread, yield_thr, c) ; /* it hasn't run yet at all, make it reach the yield */ protothread_run(pt) ; for (i = 0; i < 10; i++) { /* make sure the protothread advances its loop */ assert(i == c->i) ; protothread_run(pt) ; } free(c) ; protothread_free(pt) ; }
static void test_ready(void) { protothread_t const pt = protothread_create() ; protothread_set_ready_function(pt, set_ready, &ready) ; bool_t more ; /* more work to do */ ready_context_t * const c = malloc(sizeof(*c)) ; /* nothing to run */ more = protothread_run(pt) ; assert(!more) ; assert(!ready) ; pt_create(pt, &c->pt_thread, ready_thr, c) ; assert(ready) ; ready = FALSE ; /* advance thread to the wait */ more = protothread_run(pt) ; assert(!more) ; assert(!ready) ; /* make the thread runnable */ pt_signal(pt, c) ; assert(ready) ; ready = FALSE ; /* should advance the thread to the pt_yield() */ more = protothread_run(pt) ; assert(more) ; assert(!ready) ; /* advance the thread to its exit, nothing ready to run */ more = protothread_run(pt) ; assert(!more) ; assert(!ready) ; free(c) ; protothread_free(pt) ; }
static void test_kill(void) { protothread_t const pt = protothread_create() ; kill_context_t * const c = calloc(2, sizeof(*c)) ; bool_t more ; /* Create the thread, kill it while it is in the run queue and make * sure it didn't run. */ pt_create(pt, &c[0].pt_thread, kill_thr, &c[0]) ; pt_kill(&c[0].pt_thread) ; more = protothread_run(pt) ; assert(!more) ; /* Try to kill it one more time, just for giggles. This may not cause any * apparent problems, but memory-checker tools like valgrind will flag * any problems created here. */ assert(!pt_kill(&c[0].pt_thread)) ; /* Create the thread, wait until it is in the wait queue, wake it, * kill it and make sure it isn't scheduled any longer. * * This actually tests killing while in the run queue (thus the same * test as above), but helps justify the following test. */ pt_create(pt, &c[0].pt_thread, kill_thr, &c[0]) ; more = protothread_run(pt) ; assert(more) ; more = protothread_run(pt) ; assert(!more) ; pt_broadcast(pt, &c[0]) ; more = protothread_run(pt) ; assert(more) ; assert(pt_kill(&c[0].pt_thread)) ; more = protothread_run(pt) ; assert(!more) ; /* Create the thread, wait until it is in the wait queue, kill it, * wake it and make sure it never scheduled again. */ pt_create(pt, &c[0].pt_thread, kill_thr, &c[0]) ; more = protothread_run(pt) ; assert(more) ; more = protothread_run(pt) ; assert(!more) ; assert(pt_kill(&c[0].pt_thread)) ; pt_broadcast(pt, &c[0]) ; more = protothread_run(pt) ; assert(!more) ; /* Create two threads, delete them one way and then * delete them the other way. */ pt_create(pt, &c[0].pt_thread, kill_thr, &c[0]) ; pt_create(pt, &c[1].pt_thread, kill_thr, &c[1]) ; assert(pt_kill(&c[0].pt_thread)) ; assert(pt_kill(&c[1].pt_thread)) ; more = protothread_run(pt) ; assert(!more) ; pt_create(pt, &c[0].pt_thread, kill_thr, &c[0]) ; pt_create(pt, &c[1].pt_thread, kill_thr, &c[1]) ; assert(pt_kill(&c[1].pt_thread)) ; assert(pt_kill(&c[0].pt_thread)) ; more = protothread_run(pt) ; assert(!more) ; free(c) ; protothread_free(pt) ; }
void ll_pushnew(LL *list, long x, long y, long z, long idx){ if(list == NULL) return; PT* add = pt_create(x,y,z,idx); if(add == NULL) return; ll_push(list,add); }