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 Creates a group of channels * @return The group of channels * @note By default, the group is empty */ lwt_cgrp_t lwt_cgrp(){ lwt_cgrp_t group = (lwt_cgrp_t)malloc(sizeof(struct lwt_cgrp)); if(!group){ return LWT_NULL; } LIST_INIT(&group->head_channels_in_group); TAILQ_INIT(&group->head_event); group->waiting_thread = NULL; group->creator_thread = lwt_current(); return group; }
/** * @brief Waits until there is a pending event in the queue * @param group The group to wait for * @return The event in the queue */ lwt_chan_t lwt_cgrp_wait(lwt_cgrp_t group){ group->waiting_thread = lwt_current(); //wait until there is an event in the queue while(!group->head_event.tqh_first){ //printf("Waiting for new event in lwt: %d\n", lwt_current()->id); lwt_block(LWT_INFO_NRECEIVING); } group->waiting_thread = NULL; lwt_chan_t channel = group->head_event.tqh_first; if(channel->num_entries == 1){ __remove_event(channel, group); } //printf("Received channel: %d with num entries: %d\n", (int)channel, channel->num_entries); return channel; }
void * fn_grpwait(lwt_chan_t c) { int i; for (i = 0 ; i < ITER ; i++) { if ((i % 7) == 0) { int j; for (j = 0 ; j < (i % 8) ; j++) lwt_yield(LWT_NULL); } lwt_snd(c, (void*)lwt_id(lwt_current())); } lwt_chan_deref(c); }
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); }
void * child_multiple_channels(lwt_chan_t main_channel){ lwt_snd(main_channel, (void *)(lwt_current()->id % ITER + 1)); lwt_chan_deref(main_channel); return 0; }