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) ;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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();
}
Esempio n. 10
0
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) ;
}
Esempio n. 11
0
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) ;
}
Esempio n. 12
0
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) ;
}
Esempio n. 13
0
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);
}
Esempio n. 14
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) ;
}
Esempio n. 15
0
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) ;
}
Esempio n. 16
0
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) ;
}
Esempio n. 17
0
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) ;
}
Esempio n. 18
0
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);
}