Exemple #1
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);
}
Exemple #2
0
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;

}
Exemple #3
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();
}
Exemple #4
0
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();
}
Exemple #5
0
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;
}
Exemple #6
0
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;
}
Exemple #7
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;

}
Exemple #8
0
/**
 * @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;
}
Exemple #9
0
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);
}
Exemple #10
0
/**
 * @brief Runs the merge sort test
 * Tests being able to create multiple child channels and joining them properly
 */
void merge_sort_test(){
	struct msort_args * args = (struct msort_args *)malloc(sizeof(struct msort_args));
	args->data = (int *)malloc(sizeof(int) * MERGE_SZ);
	args->swap = (int *)malloc(sizeof(int) * MERGE_SZ);
	args->begin_index = 0;
	args->end_index = MERGE_SZ;

	//prep data
	int index;
	srand(time(NULL));
	printf("Data is: [");
	for(index = 0; index < MERGE_SZ; ++index){
		args->data[index] = rand();
		printf(" %d", args->data[index]);
	}
	printf("]\n");

	//create channel
	lwt_chan_t main_channel = lwt_chan(0);
	//create child worker
	lwt_t child = lwt_create_chan(msort, main_channel, 0);
	//receive child channel
	lwt_chan_t child_channel = lwt_rcv_chan(main_channel);
	//send args
	printf("SEND TO CHILDREN\n");
	lwt_snd(child_channel, args);
	printf("SEND COMPLETE\n");
	//receive args
	assert(lwt_rcv(main_channel));
	//join child
	lwt_join(child);
	//dereference channel
	printf("child channel\n");
	lwt_chan_deref(child_channel);
	printf("main channel\n");
	lwt_chan_deref(main_channel);
	//validate args
	int prev = args->data[0];
	printf("Sorted data: [ %d", prev);
	for(index = 1; index < MERGE_SZ; ++index){
		assert(args->data[index] >= prev);
		prev = args->data[index];
		printf(" %d", prev);
	}
	printf("]\n");
	//free data
	free(args->data);
	free(args->swap);
	free(args);
}
Exemple #11
0
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);
	}
	lwt_chan_t c = lwt_chan(0);
	chld = lwt_create(fn_nested_joins, (void*)1, 0, c);
	lwt_join(chld);
}
Exemple #12
0
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;
}
Exemple #13
0
int test_kthd_iter()
{
	lwt_chan_t c = lwt_chan(3);

	unsigned long long start, end;
	rdtscll(start);
	
	int i=0;
	for(i=0; i< ITER; i++)
		lwt_kthd_create(&fn, (void*)0x1, c);

	rdtscll(end);

	printf("%lld <- kthd_create\n", (end-start)/(ITER));
	return 0;
}
Exemple #14
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;
}
Exemple #15
0
void multiple_channels_test_v3(){
	lwt_chan_t main_channel = lwt_chan(ITER);
	lwt_t * threads = (lwt_t *)malloc(sizeof(lwt_t) * ITER);
	int index;
	for(index = 0; index < ITER; ++index){
		threads[index] = lwt_create_chan(child_multiple_channels, main_channel, LWT_NOJOIN);
	}
	int count = 0;
	for(index = 0; index < ITER; ++index){
		printf("CURRENT INDEX: %d\n", index);
		count += (int)lwt_rcv(main_channel);
	}
	lwt_chan_deref(main_channel);
	free(threads);
	assert(count == 3240);
	printf("COUNT: %d\n", count);
}
Exemple #16
0
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;
}
Exemple #17
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);
}
Exemple #18
0
/**
 * @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;
}
Exemple #19
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;
}
Exemple #20
0
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;
}
Exemple #21
0
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);
}
Exemple #22
0
/**
 * @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;
}