int test_speed_create_join() { int i=0; unsigned long long start, end; lwt_t tid1, tid2, tid3; tid1 = lwt_create(fn, NULL, 0, 0); lwt_join(tid1); IS_RESET(); rdtscll(start); for(i=0 ; i < ITER; i++) { tid1 = lwt_create(fn, NULL, 0, 0); lwt_join(tid1); } rdtscll(end); IS_RESET(); printf("performance of fork/join: --> %lld\n", (end-start)/ITER); for(i=0 ; i < ITER; i++) { tid1 = lwt_create(fn, NULL, 0, 0); tid2 = lwt_create(fn, NULL, 0, 0); tid3 = lwt_create(fn, NULL, 0, 0); lwt_join(tid3); lwt_join(tid1); lwt_join(tid2); } IS_RESET(); return 0; }
void test_perf(void) { lwt_t chld1, chld2; int i; unsigned long long start, end; /* Performance tests */ rdtscll(start); for (i = 0 ; i < ITER ; i++) { lwt_chan_t c = lwt_chan(0); chld1 = lwt_create(fn_null, NULL, 0, c); lwt_join(chld1); } rdtscll(end); printf("[PERF] %lld <- fork/join\n", (end-start)/ITER); IS_RESET(); lwt_chan_t c1 = lwt_chan(0); chld1 = lwt_create(fn_bounce, (void*)1, 0, c1); lwt_chan_t c2 = lwt_chan(0); chld2 = lwt_create(fn_bounce, NULL, 0, c2); lwt_join(chld1); lwt_join(chld2); IS_RESET(); }
void test_crt_join_sched(void) { lwt_t chld1, chld2; printf("[TEST] thread creation/join/scheduling\n"); /* functional tests: scheduling */ lwt_yield(LWT_NULL); lwt_chan_t c1 = lwt_chan(0); chld1 = lwt_create(fn_sequence, (void*)1, 0, c1); lwt_chan_t c2 = lwt_chan(0); chld2 = lwt_create(fn_sequence, (void*)2, 0, c2); lwt_join(chld2); lwt_join(chld1); IS_RESET(); /* functional tests: join */ lwt_chan_t c3 = lwt_chan(0); chld1 = lwt_create(fn_null, NULL, 0, c3); lwt_join(chld1); IS_RESET(); lwt_chan_t c4 = lwt_chan(0); chld1 = lwt_create(fn_null, NULL, 0, c4); lwt_yield(LWT_NULL); lwt_join(chld1); IS_RESET(); lwt_chan_t c5 = lwt_chan(0); chld1 = lwt_create(fn_nested_joins, NULL, 0, c5); lwt_join(chld1); IS_RESET(); /* functional tests: join only from parents */ lwt_chan_t c6 = lwt_chan(0); chld1 = lwt_create(fn_identity, (void*)0x37337, 0, c6); lwt_chan_t c7 = lwt_chan(0); chld2 = lwt_create(fn_join, chld1, 0, c7); lwt_yield(LWT_NULL); lwt_yield(LWT_NULL); lwt_join(chld2); lwt_join(chld1); IS_RESET(); /* functional tests: passing data between threads */ lwt_chan_t c8 = lwt_chan(0); chld1 = lwt_create(fn_identity, (void*)0x37337, 0, c8); assert((void*)0x37337 == lwt_join(chld1)); IS_RESET(); /* functional tests: directed yield */ lwt_chan_t c9 = lwt_chan(0); chld1 = lwt_create(fn_null, NULL, 0, c9); lwt_yield(chld1); assert(lwt_info(LWT_INFO_NTHD_ZOMBIES) == 1); lwt_join(chld1); IS_RESET(); }
void test_speed_yield() { lwt_t tid1, tid2; tid1 = lwt_create(fn_bounce, (void*)1, 0, 0); tid2 = lwt_create(fn_bounce, NULL, 0, 0); lwt_yield(LWT_NULL); lwt_join(tid1); lwt_join(tid2); lwt_yield(LWT_NULL); IS_RESET(); }
int main () { lwt_init(QUANTUM); lwt *t1 = lwt_create("foo", 0, NULL, foo); //lwt_run(t1); lwt *t2 = lwt_create("bar", 0, NULL, bar); //lwt_run(t2); int s1 = thrd_wait(t1); int s2 = thrd_wait(t2); lwt_del(t1); lwt_del(t2); printf("Achieve with status: %d\n", s1); printf("Achieve with status: %d\n", s2); lwt_exit(5); }
int test_grp_wait_with_buffer() { lwt_chan_t main_c = lwt_chan(1); lwt_t id1 = lwt_create(grp_wait_snder, (void*)main_c, 0, 0); lwt_chan_t snd_c = lwt_rcv_chan(main_c); lwt_t id2 = lwt_create(grp_wait_rcver, (void*)main_c, 0, 0); lwt_chan_t rcv_c = lwt_rcv_chan(main_c); lwt_snd_chan(rcv_c, snd_c); lwt_join(id1); lwt_join(id2); return 0; }
void test_perf_channels(int chsz) { lwt_chan_t from, to; lwt_t t; int i; unsigned long long start, end; assert(RUNNABLE == lwt_current()->state); from = lwt_chan(chsz); assert(from); lwt_chan_grant(from); lwt_chan_t c = lwt_chan(0); t = lwt_create(fn_chan, from, 0, c); to = lwt_rcv_chan(from); assert(to->snd_cnt); rdtscll(start); for (i = 0 ; i < ITER ; i++) { assert(1 == (int)lwt_rcv(from)); lwt_snd(to, (void*)2); } lwt_chan_deref(to); rdtscll(end); printf("[PERF] %lld <- snd+rcv (buffer size %d)\n", (end-start)/(ITER*2), chsz); lwt_join(t); }
/** * @brief Initializes the LWT by wrapping the current thread as a LWT */ __attribute__((constructor)) void __init__(){ //assert pool size >= 1 assert(POOL_SIZE >= 1); lwt_t curr_thread = (lwt_t)malloc(sizeof(struct lwt)); assert(curr_thread); __init_kthd(curr_thread); __init_lwt_main(curr_thread); //set up pool int num_threads; LIST_INIT(&head_ready_pool_threads); lwt_t new_pool_thread; for(num_threads = 0; num_threads < POOL_SIZE; ++num_threads){ new_pool_thread = (lwt_t)malloc(sizeof(struct lwt)); assert(new_pool_thread); __init_new_lwt(new_pool_thread); __reinit_lwt(new_pool_thread); } //buffer thread is special lwt_kthd_t pthread_kthd = __get_kthd(); pthread_kthd->buffer_thread = lwt_create(__lwt_buffer, NULL, LWT_NOJOIN); TAILQ_REMOVE(&__get_kthd()->head_runnable_threads, pthread_kthd->buffer_thread, runnable_threads); LIST_REMOVE(pthread_kthd->buffer_thread, current_threads); LIST_REMOVE(pthread_kthd->buffer_thread, siblings); LIST_REMOVE(pthread_kthd->buffer_thread, lwts_in_kthd); //pthread_kthd->buffer_thread->info = LWT_INFO_NTHD_BLOCKED; //set up mutex and cv pthread_mutex_init(&pthread_kthd->blocked_mutex, NULL); pthread_cond_init(&pthread_kthd->blocked_cv, NULL); }
void test_multisend(int chsz) { lwt_chan_t c; lwt_t t1, t2; int i, ret[ITER*2], sum = 0, maxcnt = 0; struct multisend_arg args[2]; printf("[TEST] multisend (channel buffer size %d)\n", chsz); c = lwt_chan(chsz); assert(c); for (i = 0 ; i < 2 ; i++) { args[i].c = c; args[i].snd_val = i+1; lwt_chan_grant(c); } t1 = lwt_create(fn_snder, &args[0], 0, c); t2 = lwt_create(fn_snder, &args[1], 0, c); for (i = 0 ; i < ITER*2 ; i++) { /*if (i % 5 == 0) lwt_yield(LWT_NULL);*/ ret[i] = (int)lwt_rcv(c); if (sndrcv_cnt > maxcnt) maxcnt = sndrcv_cnt; sndrcv_cnt--; } lwt_join(t1); lwt_join(t2); for (i = 0 ; i < ITER*2 ; i++) { sum += ret[i]; assert(ret[i] == 1 || ret[i] == 2); } assert(sum == (ITER * 1) + (ITER*2)); /* * This is important: Asynchronous means that the buffer * should really fill up here as the senders never block until * the buffer is full. Thus the difference in the number of * sends and the number of receives should vary by the size of * the buffer. If your implementation doesn't do this, it is * doubtful you are really doing asynchronous communication. */ assert(maxcnt >= chsz); return; }
int test_nojoin() { lwt_create(fn, NULL, LWT_FLAG_NOJOIN, NULL); assert(num_of_threads == 2); lwt_yield(_LWT_NULL); assert(num_of_threads == 1); return 0; }
int main(int argc, char *argv[]){ int i,j; lwt_thread *t; lwt_init(); empty = lwt_createS(size); full = lwt_createS(0); lock = lwt_createS(1); for(i=0;i<4;i++){ t = lwt_create(producter, NULL); lwt_run(t); } for(i=0; i<2;i++){ t = lwt_create(consumer, NULL); lwt_run(t); } lwt_wait(t); }
void test_crt_join_sched(void) { lwt_t chld1, chld2; /* functional tests: scheduling */ lwt_yield(LWT_NULL); chld1 = lwt_create(fn_sequence, (void*)1); chld2 = lwt_create(fn_sequence, (void*)2); lwt_join(chld2); lwt_join(chld1); IS_RESET(); /* functional tests: join */ chld1 = lwt_create(fn_null, NULL); lwt_join(chld1); IS_RESET(); chld1 = lwt_create(fn_null, NULL); lwt_yield(LWT_NULL); lwt_join(chld1); IS_RESET(); chld1 = lwt_create(fn_nested_joins, NULL); lwt_join(chld1); IS_RESET(); /* functional tests: join only from parents */ chld1 = lwt_create(fn_identity, (void*)0x37337); chld2 = lwt_create(fn_join, chld1); lwt_yield(LWT_NULL); lwt_yield(LWT_NULL); lwt_join(chld2); lwt_join(chld1); IS_RESET(); /* functional tests: passing data between threads */ chld1 = lwt_create(fn_identity, (void*)0x37337); assert((void*)0x37337 == lwt_join(chld1)); IS_RESET(); /* functional tests: directed yield */ chld1 = lwt_create(fn_null, NULL); lwt_yield(chld1); assert(lwt_info(LWT_INFO_NTHD_ZOMBIES) == 1); lwt_join(chld1); IS_RESET(); }
void * fn_nested_joins(void *d) { lwt_t chld; if (d) { lwt_yield(LWT_NULL); lwt_yield(LWT_NULL); assert(lwt_info(LWT_INFO_NTHD_RUNNABLE) == 1); lwt_die(NULL); } chld = lwt_create(fn_nested_joins, (void*)1); lwt_join(chld); }
void test_function_basic() { lwt_t id; IS_RESET(); id = lwt_create(fn_nested_create, 0, 0, 0); lwt_yield(LWT_NULL); printf("join in parent\n"); lwt_join(id); lwt_yield(LWT_NULL); IS_RESET(); }
void test_grpwait(int chsz, int grpsz) { lwt_chan_t cs[grpsz]; lwt_t ts[grpsz]; int i; lwt_cgrp_t g; printf("[TEST] group wait (channel buffer size %d, grpsz %d)\n", chsz, grpsz); g = lwt_cgrp(); assert(g); for (i = 0 ; i < grpsz ; i++) { cs[i] = lwt_chan(chsz); assert(cs[i]); lwt_chan_grant(cs[i]); lwt_chan_t c = lwt_chan(0); ts[i] = lwt_create(fn_grpwait, cs[i], 0, c); lwt_chan_mark_set(cs[i], (void*)lwt_id(ts[i])); lwt_cgrp_add(g, cs[i], LWT_CHAN_RCV); } assert(lwt_cgrp_free(g) == -1); /** * Q: why don't we iterate through all of the data here? * * A: We need to fix 1) cevt_wait to be level triggered, or 2) * provide a function to detect if there is data available on * a channel. Either of these would allows us to iterate on a * channel while there is more data pending. */ for (i = 0 ; i < ((ITER * grpsz)-(grpsz*chsz)) ; i++) { lwt_chan_t c; int r; lwt_chan_dir_t direction; c = lwt_cgrp_wait(g, &direction); assert(c); assert(direction == LWT_CHAN_RCV); r = (int)lwt_rcv(c); assert(r == (int)lwt_chan_mark_get(c)); } for (i = 0 ; i < grpsz ; i++) { lwt_cgrp_rem(g, cs[i]); lwt_join(ts[i]); lwt_chan_deref(cs[i]); } assert(!lwt_cgrp_free(g)); return; }
void test_perf(void) { lwt_t chld1, chld2; int i; unsigned long long start, end; /* Performance tests */ rdtscll(start); for (i = 0 ; i < ITER ; i++) { chld1 = lwt_create(fn_null, NULL); lwt_join(chld1); } rdtscll(end); printf("Overhead for fork/join is %lld\n", (end-start)/ITER); IS_RESET(); chld1 = lwt_create(fn_bounce, (void*)1); chld2 = lwt_create(fn_bounce, NULL); lwt_join(chld1); lwt_join(chld2); IS_RESET(); }
void test_multisend(void) { lwt_chan_t c; lwt_t t1, t2; int i, ret[4], sum = 0; struct multisend_arg args[2]; c = lwt_chan(0); assert(c); for (i = 0 ; i < 2 ; i++) { args[i].c = c; args[i].snd_val = i+1; } t1 = lwt_create(fn_snder, &args[0]); //print_sq(&args[0].c); t2 = lwt_create(fn_snder, &args[1]); for (i = 0 ; i < 4 ; i++) { //printf("before receive.\n"); ret[i] = (int)lwt_rcv(c); } lwt_join(t1); lwt_join(t2); for (i = 0 ; i < 4 ; i++) { sum += ret[i]; assert(ret[i] == 1 || ret[i] == 2); } assert(sum == 6); return; }
void* fn_nested_create(void* data, lwt_chan_t c) { int param = (int)data; lwt_t id; if(param< 5) { printf("create: %d\n", param); id = lwt_create(fn_nested_create, (void*)(param+1), 0, 0); lwt_yield(id); printf("join: %d\n", param); lwt_join(id); } lwt_yield(LWT_NULL); return NULL; }
void test_perf_async_steam(int chsz) { lwt_chan_t from; lwt_t t; int i; unsigned long long start, end; async_sz = chsz; assert(RUNNABLE == lwt_current()->state); from = lwt_chan(chsz); assert(from); lwt_chan_grant(from); lwt_chan_t cfix = lwt_chan(0); t = lwt_create(fn_async_steam, from, 0, cfix); assert(lwt_info(LWT_INFO_NTHD_RUNNABLE) == 2); rdtscll(start); for (i = 0 ; i < ITER ; i++) assert(i+1 == (int)lwt_rcv(from)); rdtscll(end); printf("[PERF] %lld <- asynchronous snd->rcv (buffer size %d)\n", (end-start)/(ITER*2), chsz); lwt_join(t); }
void test_perf_channels(void) { lwt_chan_t from, to; lwt_t t; int i; unsigned long long start, end; assert(_TCB_ACTIVE == lwt_current()->state); from = lwt_chan(0); assert(from); t = lwt_create(fn_chan, from); to = lwt_rcv_chan(from); rdtscll(start); for (i = 0 ; i < ITER ; i++) { assert(1 == (int)lwt_rcv(from)); lwt_snd(to, (void*)2); } lwt_chan_deref(to); rdtscll(end); printf("Overhead for snd/rcv is %lld\n", (end-start)/(ITER*2)); lwt_join(t); }
int main(int argc, char *argv[]){ int i,j; lwt *t; emptyCount = smphr_create(N); fullCount = smphr_create(0); useQueue = smphr_create(1); lwt_init(QUANTUM); lwt_create("p1", 0, NULL, producer); lwt_create("p2", 0, NULL, producer); lwt_create("p3", 0, NULL, producer); lwt_create("p4", 0, NULL, producer); lwt_create("c1", 0, NULL, consumer); t = lwt_create("c2", 0, NULL, consumer); thrd_wait(t); printf("Two Consumers consume 30 items!\n"); printf("Done!\n"); }
/* #define IS_RESET() \ assert( lwt_info(LWT_INFO_NTHD_RUNNABLE) == 1 && \ lwt_info(LWT_INFO_NTHD_ZOMBIES) == 0 && \ lwt_info(LWT_INFO_NTHD_BLOCKED) == 0) */ int main(void) { lwt_t chld1, chld2; int i; unsigned long long start, end; /* Performance tests */ rdtscll(start); for (i = 0 ; i < ITER ; i++) { chld1 = lwt_create(fn_null, NULL); lwt_join(chld1); } rdtscll(end); printf("Overhead for fork/join is %lld\n", (end-start)/ITER); //IS_RESET(); chld1 = lwt_create(fn_bounce, NULL); chld2 = lwt_create(fn_bounce, NULL); lwt_join(chld1); lwt_join(chld2); //IS_RESET(); /* functional tests: scheduling */ lwt_yield(LWT_NULL); chld1 = lwt_create(fn_sequence, (void*)1); chld2 = lwt_create(fn_sequence, (void*)2); lwt_join(chld2); lwt_join(chld1); //IS_RESET(); /* functional tests: join */ chld1 = lwt_create(fn_null, NULL); lwt_join(chld1); //IS_RESET(); chld1 = lwt_create(fn_null, NULL); lwt_yield(LWT_NULL); lwt_join(chld1); //IS_RESET(); chld1 = lwt_create(fn_nested_joins, NULL); lwt_join(chld1); //IS_RESET(); /* functional tests: join only from parents */ chld1 = lwt_create(fn_identity, (void*)0x37337); chld2 = lwt_create(fn_join, chld1); lwt_yield(LWT_NULL); lwt_yield(LWT_NULL); lwt_join(chld2); lwt_join(chld1); //IS_RESET(); /* functional tests: passing data between threads */ chld1 = lwt_create(fn_identity, (void*)0x37337); //TODO assert((void*)0x37337 == lwt_join(chld1)); //IS_RESET(); /* functional tests: directed yield */ chld1 = lwt_create(fn_null, NULL); lwt_yield(chld1); //assert(lwt_info(LWT_INFO_NTHD_ZOMBIES) == 1); lwt_join(chld1); //IS_RESET(); //TODO assert(thd_cnt == ITER+12); }