void* grp_wait_rcver(void* param, lwt_chan_t c) { lwt_chan_t cc = lwt_chan(10); lwt_snd_chan((lwt_chan_t)param, cc); lwt_chan_t cc2 = lwt_rcv_chan(cc); lwt_cgrp_t cg = lwt_cgrp(); int i=0; for(i=0; i < ITER; i++) { lwt_chan_t cci = lwt_chan(3); assert(lwt_cgrp_add(cg, cci, LWT_CHAN_RCV) == 0); printf("in_main: thread %d: sending channel %d\n", current_tid, i); lwt_snd_chan(cc2, cci); printf("in_main: thread %d: channel %d sent\n", current_tid, i); } while(i>0) { printf("in_main: thread %d: group waiting\n", current_tid); lwt_chan_t cci = lwt_cgrp_wait(cg, LWT_CHAN_RCV); printf("in_main: thread %d: cci rcved, start rcv data\n", current_tid); i = (int)lwt_rcv(cci); printf("in_main: thread %d: i rcved: %d\n", current_tid, i); } return NULL; }
int test_kthd() { lwt_chan_t rcv_c = lwt_chan(0); lwt_chan_t snd_c = lwt_chan(0); lwt_kthd_create(&kthd_rcv_print, (void*)0x1, rcv_c); lwt_kthd_create(&kthd_snd_print, (void*)0x1, snd_c); lwt_chan_t main_c = lwt_chan(0); lwt_snd_chan(rcv_c, main_c); lwt_chan_t cc = lwt_rcv_chan(main_c); lwt_snd_chan(snd_c, cc); // sleep(1); //kthd_snd_print(rcv_c); return 0; }
void* grp_wait_snder(void* param, lwt_chan_t c) { lwt_chan_t cc2 = lwt_chan(10); lwt_snd_chan((lwt_chan_t)param, cc2); lwt_chan_t cg_a[ITER]; int i=0; for(i=0; i<ITER; i++) { printf("in_main: thread %d: waiting incoming channel %d\n", current_tid, i); cg_a[i] = lwt_rcv_chan(cc2); printf("in_main: thread %d: channel %d rcved.\n", current_tid, i); } i--; for(;i>=0; i--) { printf("in_main: thread %d: sending %d\n", current_tid, i); lwt_snd(cg_a[i], (void*)i); printf("in_main: thread %d: %d sent\n", current_tid, i); } return NULL; }
/** * @brief Receives a count, updates it and sends it back * @param main_channel The channel from the main thread * @return 0 if successful */ void * child_pong(lwt_chan_t main_channel){ printf("Starting child function 2\n"); //create the channel lwt_chan_t child_2_channel = lwt_chan(0); //send it to parent lwt_snd_chan(main_channel, child_2_channel); //receive child 1 channel lwt_chan_t child_1_channel = lwt_rcv_chan(child_2_channel); int count = (int)lwt_rcv(child_2_channel); while(count < 100){ printf("CHILD 2 COUNT: %d\n", count); //update count count++; printf("SENDING COUNT TO CHILD 1\n"); lwt_snd(child_1_channel, (int)count); if(count >= 100){ break; } printf("RECEVING COUNT FROM CHILD 1\n"); count = (int)lwt_rcv(child_2_channel); } lwt_chan_deref(main_channel); lwt_chan_deref(child_1_channel); lwt_chan_deref(child_2_channel); printf("CHILD 2 COUNT: %d\n", count); return 0; }
/** * @brief Runs the ping/pong test */ void ping_pong_test(){ printf("Starting channels test\n"); //create channel lwt_chan_t main_channel = lwt_chan(0); //create child threads lwt_t ping_lwt = lwt_create_chan(child_ping, main_channel, 0); lwt_t * pong_lwts = (lwt_t *)malloc(sizeof(lwt_t) * ITER); int index; for(index = 0; index < ITER; ++index){ pong_lwts[index] = lwt_create_chan(child_pong, main_channel, 0); } //receive channels lwt_chan_t ping_channel = lwt_rcv_chan(main_channel); lwt_chan_t * pong_channels = (lwt_chan_t *)malloc(sizeof(lwt_chan_t) * ITER); for(index = 0; index < ITER; ++index){ pong_channels[index] = lwt_rcv_chan(main_channel); } //send channels for(index = 0; index < ITER; ++index){ lwt_snd_chan(pong_channels[index], ping_channel); } for(index = 0; index < ITER; ++index){ lwt_snd_chan(ping_channel, pong_channels[index]); } //we're done with the channels lwt_chan_deref(ping_channel); for(index = 0; index < ITER; ++index){ lwt_chan_deref(pong_channels[index]); } lwt_chan_deref(main_channel); free(pong_channels); //join threads lwt_join(ping_lwt); for(index = 0; index < ITER; ++index){ lwt_join(pong_lwts[index]); } free(pong_lwts); }
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 * fn_chan(lwt_chan_t to) { lwt_chan_t from; int i; from = lwt_chan(0); lwt_snd_chan(to, from); assert(from->snd_cnt); for (i = 0 ; i < ITER ; i++) { lwt_snd(to, (void*)1); assert(2 == (int)lwt_rcv(from)); } lwt_chan_deref(from); return NULL; }
/** * @brief Ping channel test * @param main_channel The channel from the main thread * @return 0 if successful * Sends count out to many siblings; tests that they receive and update it properly */ void * child_ping(lwt_chan_t main_channel){ printf("Starting child ping channel\n"); //create the channel lwt_chan_t child_1_channel = lwt_chan(0); //send it to parent lwt_snd_chan(main_channel, child_1_channel); //receive children channels lwt_chan_t * children = (lwt_chan_t *)malloc(sizeof(lwt_chan_t) * ITER); int count = 1; int index; for(index = 0; index < ITER; ++index){ children[index] = lwt_rcv_chan(child_1_channel); } while(count < 100){ printf("PING COUNT: %d\n", count); //send count for(index = 0; index < ITER; ++index){ lwt_snd(children[index], (void *)count); } printf("PONG COUNT\n"); //receive count count = (int)lwt_rcv(child_1_channel); for(index = 1; index < ITER; ++index){ assert(count == (int)lwt_rcv(child_1_channel)); } if(count >= 100){ break; } //update count count++; } lwt_chan_deref(main_channel); for(index = 0; index < ITER; ++index){ lwt_chan_deref(children[index]); } free(children); lwt_chan_deref(child_1_channel); printf("CHILD 1 COUNT: %d\n", count); return 0; }
void* kthd_rcv_print(void* data, lwt_chan_t rcv_c) { printf("in kthd: data: %d and channel 0x%08x rcvd!\n", (int)data, (unsigned int)rcv_c); lwt_chan_t cc = lwt_chan(0); lwt_chan_t main_c = lwt_rcv_chan(rcv_c); lwt_snd_chan(main_c, cc); /* void* pkg = lwt_rcv(cc); printf("in kthd: data %d rcvd!\n", (int)pkg); pkg = lwt_rcv(cc); printf("in kthd: data %d rcvd!\n", (int)pkg); pkg = lwt_rcv(cc); printf("in kthd: data %d rcvd!\n", (int)pkg); pkg = lwt_rcv(cc); printf("in kthd: data %d rcvd!\n", (int)pkg); pkg = lwt_rcv(cc); printf("in kthd: data %d rcvd!\n", (int)pkg); */ lwt_cgrp_t cg = lwt_cgrp(); lwt_cgrp_add(cg, cc, LWT_CHAN_RCV); lwt_chan_t actived; printf("====start wait====\n"); while((actived = lwt_cgrp_wait(cg, LWT_CHAN_RCV)) != NULL) { assert(actived == cc); void* pkg = lwt_rcv(actived); printf("in kthd: data %d rcvd!\n", (int)pkg); } printf("====end wait====\n"); return NULL; }
/** * @brief Merge sort in parallel * @param main_channel The channel from the main thread * @return 0 if successful * @note Adapted from wikipedia: http://en.wikipedia.org/wiki/Merge_sort#Parallel_merge_sort) */ void * msort(lwt_chan_t main_channel){ //create channel lwt_chan_t my_channel = lwt_chan(0); //send channel back lwt_snd_chan(main_channel, my_channel); //receive args struct msort_args * args = lwt_rcv(my_channel); if(args->end_index - args->begin_index < 2){ //send channels lwt_snd(main_channel, args); //dereference channels lwt_chan_deref(my_channel); lwt_chan_deref(main_channel); return 0; } int middle_index = (args->begin_index + args->end_index)/2; struct msort_args * l_args = (struct msort_args *)malloc(sizeof(struct msort_args)); l_args->data = args->data; l_args->swap = args->swap; l_args->begin_index = args->begin_index; l_args->end_index = middle_index; struct msort_args * r_args = (struct msort_args *)malloc(sizeof(struct msort_args)); r_args->data = args->data; r_args->swap = args->swap; r_args->begin_index = middle_index; r_args->end_index = args->end_index; //create threads lwt_t l_lwt = lwt_create_chan(msort, my_channel, 0); lwt_t r_lwt = lwt_create_chan(msort, my_channel, 0); //receive child channels lwt_chan_t l_chan = lwt_rcv_chan(my_channel); lwt_chan_t r_chan = lwt_rcv_chan(my_channel); //send args lwt_snd(l_chan, l_args); lwt_snd(r_chan, r_args); //receive new args assert(lwt_rcv(my_channel)); assert(lwt_rcv(my_channel)); //join threads assert(lwt_join(l_lwt) == 0); assert(lwt_join(r_lwt) == 0); //dereference channels lwt_chan_deref(l_chan); lwt_chan_deref(r_chan); printf("DEREF MY CHILD CHANNEL: %d\n", (int)my_channel); lwt_chan_deref(my_channel); //free args free(l_args); free(r_args); //merge int index; int l_head = args->begin_index; int r_head = middle_index; for(index = args->begin_index; index < args->end_index; ++index){ if(l_head < middle_index && (r_head >= args->end_index || args->data[l_head] <= args->data[r_head])){ args->swap[index] = args->data[l_head]; l_head++; } else{ args->swap[index] = args->data[r_head]; r_head++; } } //copy swap into data for(index = args->begin_index; index < args->end_index; ++index){ args->data[index] = args->swap[index]; } //send updated args back lwt_snd(main_channel, args); //dereference main channel lwt_chan_deref(main_channel); return 0; }