Linked List with read-write locks for the entire linked list in C


Introduction

his implementation support Member( )Insert( ), and Delete( ) functions. Populate the linked list with n random, but unique values. Each value should be between 0 and 2^16– 1. Then perform m random Member, Insert, and Delete operations on the link list. Let mMember, mInsert, and mDelete be the fractions of operations of each type. You may use any values within 0 and 2^16– 1 while performing these three operations.

However, to simplify the implementation, a new value inserted into the list cannot be a value already in the list (it may be a value that was initially added to the list, but later removed).

 

Code


/* File:     serial_linked_list .c
 * Purpose:  Implement a linked list as a Parallel program (based on Pthreads) with read-write locks for the entire linked list 
 * 			 Implementation should support Member( ), Insert( ), and Delete( ) functions. 
 *			 Populate the linked list with n random, but unique values. 
 * 			 Each value should be between 0 and 2^16 - 1.
 * 			 Then perform m random Member, Insert, and Delete operations on the link list.
 * 			 Let mMember, mInsert, and mDelete be the fractions of operations of each type.
 * 			 You may use any values within 0 and 2^16 – 1 while performing these three operations.
 * 			 However, to simplify the implementation, a new value inserted into the list cannot be a 
 * 			 value already in the list (it may be a value that was initially added to the list, but later removed).
 *
 * Compile:  gcc -g -Wall -o parallel_link_list_2 parallel_link_list_2.c -pthread
 *           
 * Run:      ./parallel_link_list_2 <number of threads><n> <m> <mMember> <mInsert> <mDelete> 
 *           n is the number of initial unique values in the Link List.
 *           m is number of random Member, Insert, and Delete operations on the link list.
 *			 mMember is the fractions of operations of Member operation.	
 *			 mInsert is the fractions of operations of Insert operation.	
 *			 mDelete is the fractions of operations of Delete operation.	
 *
 * Input:    none
 * 
 * Output:   This version prints the elapsed time required for
 *           Parallel program (based on Pthreads) with read-write locks for the entire linked list  calculations.
 *
 * Notes:
 *      	CS4532 Concurrent Programming 
 *			Take Home Lab 1 
 *			Due – Jun 28 before 11:55 PM  
 *
 * Date:	07/25/2014
 *
 * Author : Wijebandara WMNC
 * 			100598M
 *			Computer Science and Engineering
 *
 * Email : chameerawijebandara@gmail.com 
 * 				
 */        

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include <time.h>

struct list_node_s
{
	int data;
	struct list_node_s* next;
};

const int MAX_THREADS = 1024;

long thread_count;
pthread_rwlock_t rwlock;
struct list_node_s* head = NULL;	

int n;
int m;
float mMember;
float mInsert;
float mDelete;
int count_member=0;
int count_insert=0;
int count_delete=0;

int member( int value, struct  list_node_s* head_p );
int insert(int value, struct list_node_s** head_pp);
int delete (int value, struct list_node_s** head_pp);
int printList( struct  list_node_s* head_p ); 
void* thread_oparation(void* rank);


/* Only executed by main thread */
void Get_args(int argc, char* argv[]);
void Usage(char* prog_name);
double Serial_pi(long long n);

/* Main function */
int main(int argc, char* argv[])
{
	int i=0;
	long       thread;  /* Use long in case of a 64-bit system */
   	pthread_t* thread_handles;
	double start, finish, elapsed;
	
	/* read command line arguments */
	Get_args(argc, argv); 
	 
	/* initially populating the link list */ 
	for(;i<n;i++)
	{	
		int r = rand()%65536;
		if(!insert(r,&head))
		{
			i--;
		}
	}
	
	
	//printf("%f\n",mMember);
	//printf("%f\n",mInsert);
		
	
	thread_handles = (pthread_t*) malloc (thread_count*sizeof(pthread_t)); 	
	
	start = clock();
	pthread_rwlock_init(&rwlock, NULL);
	
	for (thread = 0; thread < thread_count; thread++)  
	{
      	pthread_create(&thread_handles[thread], NULL,thread_oparation , (void*)thread);  
	}
	
   	for (thread = 0; thread < thread_count; thread++) 
    {
     	pthread_join(thread_handles[thread], NULL); 
	}
	
	pthread_rwlock_destroy(&rwlock);
	finish = clock();
   	elapsed = (finish - start)/CLOCKS_PER_SEC;
   	
   	printf("Elapsed time = %e seconds\n", elapsed);
   	
   	//printf("%.10f,\n", elapsed);
	//printf("Member operation count = %d\n",count_member);
	//printf("Insert operation count = %d\n",count_insert);
	//printf("Delete operation count = %d\n",count_delete);
	//printList(head);
	return 0;
}/*main*/	

/*------------------------------------------------------------------
 * Function:       thread_oparation 
 * Purpose:        Compleetea the link list oparations by the thread running this 
 * In arg:         rank
 * Ret val:        ignored
 * Globals in:     n, thread_count, mMember, mInsert, mDelete
 * Global in/out:  count_member, count_insert, count_delete 
 */
void* thread_oparation(void* rank) 
{
	long my_rank = (long) rank;
	double factor, my_sum = 0.0;
	long long i;
	long long my_m = m/thread_count;
	for( i=0; i< my_m; i++ )
	{

		float prob = (rand()%10000/10000.0);
		//printf("%f\n",prob);
	
	
		int r = rand()%65536;
		if(prob < mMember)
		{
			pthread_rwlock_rdlock(&rwlock);
			member(r,head);
			count_member++;
			pthread_rwlock_unlock(&rwlock);
		}
		else if(prob < mMember + mInsert )
		{
			pthread_rwlock_wrlock(&rwlock);
			insert(r,&head);
			count_insert++;
			pthread_rwlock_unlock(&rwlock);
		}
		else
		{			
			pthread_rwlock_wrlock(&rwlock);
			delete(r,&head);
			count_delete++;
			pthread_rwlock_unlock(&rwlock);
		}
	
	}
   

   return NULL;
}  /* Thread_sum */

/*------------------------------------------------------------------
 * Function:       member
 * Purpose:        Check if the given values is in the link list
 * In arg:         value, head_p
 * Globals in:     
 * Global in/out:   
 * Return val: Return 1 if value exist otherwise 0
 */
int member( int value, struct  list_node_s* head_p )
{
	struct list_node_s* curr_p = head_p;
	
	while( curr_p != NULL && curr_p->data < value )
	{
		curr_p = curr_p->next;
	}

	if(curr_p == NULL || curr_p->data > value)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}/* member */

/*------------------------------------------------------------------
 * Function:       insert
 * Purpose:        Add new values in to link list
 * In arg:         value, head_p
 * Globals in:  
 * Global in/out:  
 * Return val: Return 1 if value successfully add to the list otherwise 0
 */
int insert(int value, struct list_node_s** head_pp)
{
	struct list_node_s* curr_p = *head_pp;			
	struct list_node_s* pred_p = NULL;
	struct list_node_s* temp_p = NULL;

	while(curr_p !=NULL && curr_p->data < value)
	{
		pred_p = curr_p;
		curr_p = curr_p->next;
	}
	
	if(curr_p == NULL || curr_p->data > value)
	{
		temp_p = malloc(sizeof(struct list_node_s));		
		temp_p->data = value;
		temp_p->next = curr_p;
		
		if(pred_p == NULL)
		{
			*head_pp = temp_p;
		}
		else
		{
			pred_p->next = temp_p;
		}
		return 1;
 
	}
	else
	{
		return 0;
	}
}	/*insert*/


/*------------------------------------------------------------------
 * Function:       delete
 * Purpose:        remove values from the link list 
 * In arg:         value, head_p
 * Globals in:     
 * Global in/out:  
 * Return val: Return 1 if value successfully remove from the list otherwise 0
 */
int delete (int value, struct list_node_s** head_pp)
{
	struct list_node_s* curr_p = *head_pp;
	struct list_node_s* pred_p = NULL;
	
	while(curr_p != NULL && curr_p->data < value)
	{
		pred_p = curr_p;
		curr_p = curr_p->next;
	}	
	
	if(curr_p != NULL && curr_p -> data < value)
	{
		if(pred_p == NULL){
			*head_pp = curr_p->next;
			free(curr_p);
		}
		else
		{
			pred_p->next = curr_p->next;
			free(curr_p);
		}
		return 1;
		
	}
	else
	{
		return 0;
	}

}	/*delete*/


/*------------------------------------------------------------------
 * Function:    Get_args
 * Purpose:     Get the command line args
 * In args:     argc, argv
 * Globals out: thread_count, n, m, mMember, mInsert, mDelete
 */
void Get_args(int argc, char* argv[]) {
	if (argc != 7)
   	{
		Usage(argv[0]);
	}
	thread_count = strtol(argv[1], NULL, 10);  
   	if (thread_count <= 0 || thread_count > MAX_THREADS)
   	{
   		Usage(argv[0]);
   	}
   
   	n = (int) strtol(argv[2], (char **)NULL, 10);
   	m = (int) strtol(argv[3], (char **)NULL, 10);
   	
   	mMember = (float) atof(argv[4]);
   	mInsert = (float) atof(argv[5]);
	mDelete = (float) atof(argv[6]);
	
   if (n <= 0 || m <= 0 || mMember + mInsert + mDelete!=1.0) Usage(argv[0]);
   
}  /* Get_args */

/*------------------------------------------------------------------
 * Function:  Usage
 * Purpose:   Print a message explaining how to run the program
 * In arg:    prog_name
 */
void Usage(char* prog_name) {
   fprintf(stderr, "usage: %s <number of threads> <n> <m> <mMember> <mInsert> <mDelete>\n", prog_name);
   fprintf(stderr,"n is the number of initial unique values in the Link List.\n");
   fprintf(stderr,"m is number of random Member, Insert, and Delete operations on the link list.\n");
   fprintf(stderr,"mMember is the fractions of operations of Member operation.\n");
   fprintf(stderr,"mInsert is the fractions of operations of Insert operation.\n");
   fprintf(stderr,"mDelete is the fractions of operations of Delete operation.\n");
   			 
   exit(0);
}  /* Usage */

/*------------------------------------------------------------------
 * Function:       printList
 * Purpose:        Add in the terms computed by the thread running this 
 * In arg:         value, head_p
 * Globals in:     
 * Global in/out:   
 * Return val: Estimate of pi using n terms of Maclaurin series
 */
int printList( struct  list_node_s* head_p ) 
{
	struct list_node_s* curr_p = head_p;
	
	while(curr_p != NULL)
	{
		printf("%d ",curr_p->data);
		curr_p = curr_p->next;
	}
	printf("\n");
}	/*printList */




Linked List with one mutex for the entire linked list in C


Introduction

his implementation support Member( )Insert( ), and Delete( ) functions. Populate the linked list with n random, but unique values. Each value should be between 0 and 2^16– 1. Then perform m random Member, Insert, and Delete operations on the link list. Let mMember, mInsert, and mDelete be the fractions of operations of each type. You may use any values within 0 and 2^16– 1 while performing these three operations.

However, to simplify the implementation, a new value inserted into the list cannot be a value already in the list (it may be a value that was initially added to the list, but later removed).

 

Code

/* File:     serial_linked_list .c
 * Purpose:  Implement a linked list as a Parallel program (based on Pthreads) with one mutex for the entire linked list 
 * 			 Implementation should support Member( ), Insert( ), and Delete( ) functions. 
 *			 Populate the linked list with n random, but unique values. 
 * 			 Each value should be between 0 and 2^16 - 1.
 * 			 Then perform m random Member, Insert, and Delete operations on the link list.
 * 			 Let mMember, mInsert, and mDelete be the fractions of operations of each type.
 * 			 You may use any values within 0 and 2^16 – 1 while performing these three operations.
 * 			 However, to simplify the implementation, a new value inserted into the list cannot be a 
 * 			 value already in the list (it may be a value that was initially added to the list, but later removed).
 *
 * Compile:  gcc -g -Wall -o parallel_link_list_1 parallel_link_list_1.c -pthread
 *           
 * Run:      ./parallel_link_list_1 <number of threads><n> <m> <mMember> <mInsert> <mDelete> 
 *           n is the number of initial unique values in the Link List.
 *           m is number of random Member, Insert, and Delete operations on the link list.
 *			 mMember is the fractions of operations of Member operation.	
 *			 mInsert is the fractions of operations of Insert operation.	
 *			 mDelete is the fractions of operations of Delete operation.	
 *
 * Input:    none
 * 
 * Output:   This version prints the elapsed time required for
 *           Parallel program (based on Pthreads) with one mutex for the entire linked list calculations.
 *
 * Notes:
 *      	CS4532 Concurrent Programming 
 *			Take Home Lab 1 
 *			Due – Jun 28 before 11:55 PM  
 *
 * Date:	07/25/2014
 *
 * Author : Wijebandara WMNC
 * 			100598M
 *			Computer Science and Engineering
 *
 * Email : chameerawijebandara@gmail.com 
 * 				
 */        

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include <time.h>

struct list_node_s
{
	int data;
	struct list_node_s* next;
};

const int MAX_THREADS = 1024;

long thread_count;
pthread_mutex_t mutex;
struct list_node_s* head = NULL;	

int n;
int m;
float mMember;
float mInsert;
float mDelete;
int count_member=0;
int count_insert=0;
int count_delete=0;

int member( int value, struct  list_node_s* head_p );
int insert(int value, struct list_node_s** head_pp);
int delete (int value, struct list_node_s** head_pp);
int printList( struct  list_node_s* head_p ); 
void* thread_oparation(void* rank);


/* Only executed by main thread */
void Get_args(int argc, char* argv[]);
void Usage(char* prog_name);
double Serial_pi(long long n);

/* Main function */
int main(int argc, char* argv[])
{
	int i=0;
	long       thread;  /* Use long in case of a 64-bit system */
   	pthread_t* thread_handles;
	double start, finish, elapsed;
	
	/* read command line arguments */
	Get_args(argc, argv); 
	 
	/* initially populating the link list */ 
	for(;i<n;i++)
	{	
		int r = rand()%65536;
		if(!insert(r,&head))
		{
			i--;
		}
	}
	
	
	//printf("%f\n",mMember);
	//printf("%f\n",mInsert);
		
	
	thread_handles = (pthread_t*) malloc (thread_count*sizeof(pthread_t)); 	
	
	start = clock();
	pthread_mutex_init(&mutex, NULL);
	
	for (thread = 0; thread < thread_count; thread++)  
	{
      	pthread_create(&thread_handles[thread], NULL,thread_oparation , (void*)thread);  
	}
	
   	for (thread = 0; thread < thread_count; thread++) 
    {
     	pthread_join(thread_handles[thread], NULL); 
	}
	
	pthread_mutex_destroy(&mutex);
	finish = clock();
   	elapsed = (finish - start)/CLOCKS_PER_SEC;
   	
   	printf("Elapsed time = %e seconds\n", elapsed);
   	
   	//printf("%.10f,\n", elapsed);
	//printf("Member operation count = %d\n",count_member);
	//printf("Insert operation count = %d\n",count_insert);
	//printf("Delete operation count = %d\n",count_delete);
	//printList(head);
	return 0;
}/*main*/	

/*------------------------------------------------------------------
 * Function:       thread_oparation 
 * Purpose:        Compleetea the link list oparations by the thread running this 
 * In arg:         rank
 * Ret val:        ignored
 * Globals in:     n, thread_count, mMember, mInsert, mDelete
 * Global in/out:  count_member, count_insert, count_delete 
 */
void* thread_oparation(void* rank) 
{
	long my_rank = (long) rank;
	double factor, my_sum = 0.0;
	long long i;
	long long my_m = m/thread_count;
	for( i=0; i < my_m; i++ )
	{

		float prob = (rand()%10000/10000.0);
		//printf("%f\n",prob);
	
	
		int r = rand()%65536;
		if(prob<mMember)
		{
			pthread_mutex_lock(&mutex);
			member(r,head);
			count_member++;
			pthread_mutex_unlock(&mutex);
		}
		else if(prob < mMember + mInsert )
		{
			pthread_mutex_lock(&mutex);
			insert(r,&head);
			count_insert++;
			pthread_mutex_unlock(&mutex);
		}
		else
		{			
			pthread_mutex_lock(&mutex);
			delete(r,&head);
			count_delete++;
			pthread_mutex_unlock(&mutex);
		}	
	}  

   return NULL;
}  /* Thread_sum */

/*------------------------------------------------------------------
 * Function:       member
 * Purpose:        Check if the given values is in the link list
 * In arg:         value, head_p
 * Globals in:     
 * Global in/out:   
 * Return val: Return 1 if value exist otherwise 0
 */
int member( int value, struct  list_node_s* head_p )
{
	struct list_node_s* curr_p = head_p;
	
	while( curr_p != NULL && curr_p->data < value )
	{
		curr_p = curr_p->next;
	}

	if(curr_p == NULL || curr_p->data > value)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}/* member */

/*------------------------------------------------------------------
 * Function:       insert
 * Purpose:        Add new values in to link list
 * In arg:         value, head_p
 * Globals in:  
 * Global in/out:  
 * Return val: Return 1 if value successfully add to the list otherwise 0
 */
int insert(int value, struct list_node_s** head_pp)
{
	struct list_node_s* curr_p = *head_pp;			
	struct list_node_s* pred_p = NULL;
	struct list_node_s* temp_p = NULL;

	while(curr_p !=NULL && curr_p->data < value)
	{
		pred_p = curr_p;
		curr_p = curr_p->next;
	}
	
	if(curr_p == NULL || curr_p->data > value)
	{
		temp_p = malloc(sizeof(struct list_node_s));		
		temp_p->data = value;
		temp_p->next = curr_p;
		
		if(pred_p == NULL)
		{
			*head_pp = temp_p;
		}
		else
		{
			pred_p->next = temp_p;
		}
		return 1;
 
	}
	else
	{
		return 0;
	}
}	/*insert*/


/*------------------------------------------------------------------
 * Function:       delete
 * Purpose:        remove values from the link list 
 * In arg:         value, head_p
 * Globals in:     
 * Global in/out:  
 * Return val: Return 1 if value successfully remove from the list otherwise 0
 */
int delete (int value, struct list_node_s** head_pp)
{
	struct list_node_s* curr_p = *head_pp;
	struct list_node_s* pred_p = NULL;
	
	while(curr_p != NULL && curr_p->data < value)
	{
		pred_p = curr_p;
		curr_p = curr_p->next;
	}	
	
	if(curr_p != NULL && curr_p -> data < value)
	{
		if(pred_p == NULL){
			*head_pp = curr_p->next;
			free(curr_p);
		}
		else
		{
			pred_p->next = curr_p->next;
			free(curr_p);
		}
		return 1;
		
	}
	else
	{
		return 0;
	}

}	/*delete*/


/*------------------------------------------------------------------
 * Function:    Get_args
 * Purpose:     Get the command line args
 * In args:     argc, argv
 * Globals out: thread_count, n, m, mMember, mInsert, mDelete
 */
void Get_args(int argc, char* argv[]) {
	if (argc != 7)
   	{
		Usage(argv[0]);
	}
	thread_count = strtol(argv[1], NULL, 10);  
   	if (thread_count <= 0 || thread_count > MAX_THREADS)
   	{
   		Usage(argv[0]);
   	}
   
   	n = (int) strtol(argv[2], (char **)NULL, 10);
   	m = (int) strtol(argv[3], (char **)NULL, 10);
   	
   	mMember = (float) atof(argv[4]);
   	mInsert = (float) atof(argv[5]);
	mDelete = (float) atof(argv[6]);
	
   if (n <= 0 || m <= 0 || mMember + mInsert + mDelete!=1.0) Usage(argv[0]);
   
}  /* Get_args */

/*------------------------------------------------------------------
 * Function:  Usage
 * Purpose:   Print a message explaining how to run the program
 * In arg:    prog_name
 */
void Usage(char* prog_name) {
   fprintf(stderr, "usage: %s <number of threads> <n> <m> <mMember> <mInsert> <mDelete>\n", prog_name);
   fprintf(stderr,"n is the number of initial unique values in the Link List.\n");
   fprintf(stderr,"m is number of random Member, Insert, and Delete operations on the link list.\n");
   fprintf(stderr,"mMember is the fractions of operations of Member operation.\n");
   fprintf(stderr,"mInsert is the fractions of operations of Insert operation.\n");
   fprintf(stderr,"mDelete is the fractions of operations of Delete operation.\n");
   			 
   exit(0);
}  /* Usage */

/*------------------------------------------------------------------
 * Function:       printList
 * Purpose:        Add in the terms computed by the thread running this 
 * In arg:         value, head_p
 * Globals in:     
 * Global in/out:   
 * Return val: Estimate of pi using n terms of Maclaurin series
 */
int printList( struct  list_node_s* head_p ) 
{
	struct list_node_s* curr_p = head_p;
	
	while(curr_p != NULL)
	{
		printf("%d ",curr_p->data);
		curr_p = curr_p->next;
	}
	printf("\n");
}	/*printList */



Linked List as a Serial Program in C


Introduction

his implementation support Member( ), Insert( ), and Delete( ) functions. Populate the linked list with n random, but unique values. Each value should be between 0 and 2^16– 1. Then perform m random Member, Insert, and Delete operations on the link list. Let mMember, mInsert, and mDelete be the fractions of operations of each type. You may use any values within 0 and 2^16– 1 while performing these three operations.

However, to simplify the implementation, a new value inserted into the list cannot be a value already in the list (it may be a value that was initially added to the list, but later removed).

 

Code


/* File:     serial_linked_list .c
 * Purpose:  Implement a linked list as a Serial program
 * 			 Implementation should support Member( ), Insert( ), and Delete( ) functions. 
 *			 Populate the linked list with n random, but unique values. 
 * 			 Each value should be between 0 and 2^16 - 1.
 * 			 Then perform m random Member, Insert, and Delete operations on the link list.
 * 			 Let mMember, mInsert, and mDelete be the fractions of operations of each type.
 * 			 You may use any values within 0 and 2^16 – 1 while performing these three operations.
 * 			 However, to simplify the implementation, a new value inserted into the list cannot be a 
 * 			 value already in the list (it may be a value that was initially added to the list, but later removed).
 *
 * Compile:  gcc -g -Wall -o serial_linked_list serial_linked_list.c -pthread
 *           
 * Run:      ./serial_linked_list <n> <m> <mMember> <mInsert> <mDelete> 
 *           n is the number of initial unique values in the Link List.
 *           m is number of random Member, Insert, and Delete operations on the link list.
 *			 mMember is the fractions of operations of Member operation.	
 *			 mInsert is the fractions of operations of Insert operation.	
 *			 mDelete is the fractions of operations of Delete operation.	
 *
 * Input:    none
 * 
 * Output:   This version prints the elapsed time required for
 *           single-threaded calculations.
 *
 * Notes:
 *      	CS4532 Concurrent Programming 
 *			Take Home Lab 1 
 *			Due – Jun 28 before 11:55 PM  
 *
 * Date:	07/25/2014
 *
 * Author : Wijebandara WMNC
 * 			100598M
 *			Computer Science and Engineering
 *
 * Email : chameerawijebandara@gmail.com 
 * 				
 */        

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include <time.h>

struct list_node_s
{
	int data;
	struct list_node_s* next;
};


int n;
int m;
float mMember;
float mInsert;
float mDelete;


int member( int value, struct  list_node_s* head_p );
int insert(int value, struct list_node_s** head_pp);
int delete (int value, struct list_node_s** head_pp);
int printList( struct  list_node_s* head_p ); 


/* Only executed by main thread */
void Get_args(int argc, char* argv[]);
void Usage(char* prog_name);
double Serial_pi(long long n);

/* Main function */
int main(int argc, char* argv[])
{
	struct list_node_s* head = NULL;	
	int i=0;
	double start, finish, elapsed;
	
	/* read command line arguments */
	Get_args(argc, argv); 
	 
	/* initially populating the link list */ 
	for(;i<n;i++)
	{	
		int r = rand()%65536;
		if(!insert(r,&head))
		{
			i--;
		}
	}
	
	int count_member=0;
	int count_insert=0;
	int count_delete=0;
	//printf("%f\n",mMember);
	//printf("%f\n",mInsert);
		
	start = clock();	
	for(i=0;i<m;i++)
	{
	
		float prob = (rand()%10000/10000.0);
		//printf("%f\n",prob);
		
		
		int r = rand()%65536;
		if(prob<mMember)
		{
			member(r,head);
			count_member++;
		}
		else if(prob < mMember + mInsert )
		{
			insert(r,&head);
			count_insert++;
		}
		else
		{			
			delete(r,&head);
			count_delete++;
		}
		
	}
	finish = clock();
   	elapsed = (finish - start)/CLOCKS_PER_SEC;
   	
   	printf("Elapsed time = %.10f seconds\n", elapsed);
   	
   	//printf("%.10f,\n", elapsed);
	//printf("Member operation count = %d\n",count_member);
	//printf("Insert operation count = %d\n",count_insert);
	//printf("Delete operation count = %d\n",count_delete);
	//printList(head);
	return 0;
}/*main*/	



/*------------------------------------------------------------------
 * Function:       member
 * Purpose:        Check if the given values is in the link list
 * In arg:         value, head_p
 * Globals in:     
 * Global in/out:   
 * Return val: Return 1 if value exist otherwise 0
 */
int member( int value, struct  list_node_s* head_p )
{
	struct list_node_s* curr_p = head_p;
	
	while( curr_p != NULL && curr_p->data < value )
	{
		curr_p = curr_p->next;
	}

	if(curr_p == NULL || curr_p->data > value)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}/* member */

/*------------------------------------------------------------------
 * Function:       insert
 * Purpose:        Add new values in to link list
 * In arg:         value, head_p
 * Globals in:  
 * Global in/out:  
 * Return val: Return 1 if value successfully add to the list otherwise 0
 */
int insert(int value, struct list_node_s** head_pp)
{
	struct list_node_s* curr_p = *head_pp;			
	struct list_node_s* pred_p = NULL;
	struct list_node_s* temp_p = NULL;

	while(curr_p !=NULL && curr_p->data < value)
	{
		pred_p = curr_p;
		curr_p = curr_p->next;
	}
	
	if(curr_p == NULL || curr_p->data > value)
	{
		temp_p = malloc(sizeof(struct list_node_s));		
		temp_p->data = value;
		temp_p->next = curr_p;
		
		if(pred_p == NULL)
		{
			*head_pp = temp_p;
		}
		else
		{
			pred_p->next = temp_p;
		}
		return 1;
 
	}
	else
	{
		return 0;
	}
}	/*insert*/


/*------------------------------------------------------------------
 * Function:       delete
 * Purpose:        remove values from the link list 
 * In arg:         value, head_p
 * Globals in:     
 * Global in/out:  
 * Return val: Return 1 if value successfully remove from the list otherwise 0
 */
int delete (int value, struct list_node_s** head_pp)
{
	struct list_node_s* curr_p = *head_pp;
	struct list_node_s* pred_p = NULL;
	
	while(curr_p != NULL && curr_p->data < value)
	{
		pred_p = curr_p;
		curr_p = curr_p->next;
	}	
	
	if(curr_p != NULL && curr_p -> data < value)
	{
		if(pred_p == NULL){
			*head_pp = curr_p->next;
			free(curr_p);
		}
		else
		{
			pred_p->next = curr_p->next;
			free(curr_p);
		}
		return 1;
		
	}
	else
	{
		return 0;
	}

}	/*delete*/


/*------------------------------------------------------------------
 * Function:    Get_args
 * Purpose:     Get the command line args
 * In args:     argc, argv
 * Globals out: n, m, mMember, mInsert, mDelete
 */
void Get_args(int argc, char* argv[]) {
	if (argc != 6)
   	{
		Usage(argv[0]);
	}
   	n = (int) strtol(argv[1], (char **)NULL, 10);
   	m = (int) strtol(argv[2], (char **)NULL, 10);
   	
   	mMember = (float) atof(argv[3]);
   	mInsert = (float) atof(argv[4]);
	mDelete = (float) atof(argv[5]);
	
   if (n <= 0 || m <= 0 || mMember + mInsert + mDelete!=1.0) Usage(argv[0]);
   
}  /* Get_args */

/*------------------------------------------------------------------
 * Function:  Usage
 * Purpose:   Print a message explaining how to run the program
 * In arg:    prog_name
 */
void Usage(char* prog_name) {
   fprintf(stderr, "usage: %s <n> <m> <mMember> <mInsert> <mDelete>\n", prog_name);
   fprintf(stderr,"n is the number of initial unique values in the Link List.");
   fprintf(stderr,"m is number of random Member, Insert, and Delete operations on the link list.");
   fprintf(stderr,"mMember is the fractions of operations of Member operation.");
   fprintf(stderr,"mInsert is the fractions of operations of Insert operation.");
   fprintf(stderr,"mDelete is the fractions of operations of Delete operation.");
   			 
   exit(0);
}  /* Usage */

/*------------------------------------------------------------------
 * Function:       printList
 * Purpose:        Add in the terms computed by the thread running this 
 * In arg:         value, head_p
 * Globals in:     
 * Global in/out:   
 * Return val: Estimate of pi using n terms of Maclaurin series
 */
int printList( struct  list_node_s* head_p ) 
{
	struct list_node_s* curr_p = head_p;
	
	while(curr_p != NULL)
	{
		printf("%d ",curr_p->data);
		curr_p = curr_p->next;
	}
	printf("\n");
}	/*printList */




Run First pthread Program in Ubuntu 14.04


Welcome to the concurrent world. 😀

Set Up the Environment


sudo apt-get install build-essential
sudo apt-get install libpthread-stubs0-dev

Sample Source  Code


#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void *print_message_function( void *ptr );

main()
{
     pthread_t thread1, thread2;
     char *message1 = "Thread 1";
     char *message2 = "Thread 2";
     int  iret1, iret2;

    /* Create independent threads each of which will execute function */

     iret1 = <a href="http://node1.yo-linux.com/cgi-bin/man2html?cgi_command=pthread_create">pthread_create</a>( &thread1, NULL, print_message_function, (void*) message1);
     iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) message2);

     /* Wait till threads are complete before main continues. Unless we  */
     /* wait we run the risk of executing an exit which will terminate   */
     /* the process and all threads before the threads have completed.   */

     <a href="http://node1.yo-linux.com/cgi-bin/man2html?cgi_command=pthread_join">pthread_join</a>( thread1, NULL);
     pthread_join( thread2, NULL); 

     printf("Thread 1 returns: %d\n",iret1);
     printf("Thread 2 returns: %d\n",iret2);
     exit(0);
}

void *print_message_function( void *ptr )
{
     char *message;
     message = (char *) ptr;
     printf("%s \n", message);
}

Compile and Run


gcc -g -Wall -o hello_pthread hello_pthread.c  -pthread

./hello_pthread

Output

 



Thread 1 
Thread 2 
Thread 1 returns: 0
Thread 2 returns: 0


If you got this output you are good to go with pthreads. 😀

ICAMES 2014 WINNERS


ICAMES is the “International Cultural and Academic Meeting of Engineering Students”, organized by the Engineering Society of Bogazici University. It is a project competition held in second week of May annually aiming to gather the different cultures from different countries in Istanbul.

20th ICAMES was held from 10th to 17th May 2014. 22 teams from 16 countries were participated for ICAMES 2014. A team consist of four undergraduates from Department of Computer Science and Engineering, University of Moratuwa was selected to participate for ICAMES this year with a project named “Shadow Mode” which had been carried out under the supervision of Mr. Nisansa de Silva, Lecturer University of Moratuwa. The team members are Sameera Nilupul, Chameera Wijebandara, Amila Perera and Akila Pemasiri.

Sri Lankan team with the project “Shadow Mode” won the first place in the ICAMES 2014.

Demo

Japan

Opening Ceremoney

Presentation

ACESO – Next Generation Diagnostic


Introduction

Magnetic Resonance Imaging (MRI) plays an increasingly vital role in the investigation of brain structure, function, development and pathologies. The capability of MRI to answer the clinically relevant questions has led a demand for analyzing techniques to be improved. In current context after an MRI scan what is given as the output is a set of 2D images that is to be examined by the radiologist and the surgeons.

These images tend to carry noise and unwanted details. This makes it harder for the radiologist as well as the surgeons to make their conclusions and the process consumes their time as well. 2D to 3D is a system that can create a 3D model using the 2D MRI scan images and detect anomalies that exist in the 3D model of the human brain.

Why it is important?

As time passes by it can be seen that the number of MRI units in hospitals has increased and the number of MRI tests has also increased. The above figures indicate data only from some selected countries. So it can be concluded that the actual number of MRI scanners and the number of MRI examinations exceeds what is shown in the graphs. This implies that the time spent by radiologists and neurologists in investigating MRI scanned images is not small. So having a system where the scanned parts can be visualized in a 3D space would save the time of doctors, radiologist as well as the patients. In a different perspective, at times when the result of the MRI scan is not for an emergency case, time spent on investigating images might not be much of an issue. But in cases of emergencies the time taken on decision making based on MRI scan results is critical. Therefore having a system where the 3D model of the MRI scan result can be obtained with the anomalies may save the time of the patient, radiologists, doctors and even will save the lives.

Architecture

mscup

“Guess the number” Game in Python


One of the simplest two-player games is “Guess the number”. The first player thinks of a secret number in some known range while the second player attempts to guess the number. After each guess, the first player answers either “Higher”, “Lower” or “Correct!” depending on whether the secret number is higher, lower or equal to the guess. In this project, you will build a simple interactive program in Python where the computer will take the role of the first player while you play as the second player.

You will interact with your program using an input field and several buttons. For this project, we will ignore the canvas and print the computer’s responses in the console. Building an initial version of your project that prints information in the console is a development strategy that you should use in later projects as well. Focusing on getting the logic of the program correct before trying to make it display the information in some “nice” way on the canvas usually saves lots of time since debugging logic errors in graphical output can be tricky.

# template for "Guess the number" mini-project
# input will come from buttons and an input field
# all output for the game will be printed in the console
import simplegui
import random

# initialize global variables used in your code
number = random.randrange(0, 10); 
count = 0
maxNumber = 100;

# helper function to start and restart the game
def new_game():
    global number, count, maxNumber
    number = random.randrange(0, maxNumber);
    if(maxNumber == 100):
        count = 7
    else:
        count = 11   
    print ""
    print "New Game. Range is from 0 to " + str(maxNumber)
    print "Number of remaining guesses is " + str(count)   

# define event handlers for control panel
def range100():
    # button that changes range to range [0,100) and restarts
    global count
    count = 100
    new_game()
    
def range1000():
    # button that changes range to range [0,1000) and restarts
    global count
    count = 1000
    new_game()
    
def input_guess(guess):
    # main game logic goes here
    global number, count
    
    print ""
    print "Guess was " + guess 
    print "Number of remaining guesses is " + str(count)
    
    if( count == 0):
        print "You ran out of guesses. The number is "+str(number)
        new_game() 
        return 
    count = count - 1
    if(int(guess)<number):
        print  "Higher"
    elif(int(guess)>number):
        print "Lower"
    else:
        print "Correct!"
        new_game() 
    
# create frame
frame = simplegui.create_frame('Guess the number', 200, 300)


# register event handlers for control elements
frame.add_button('Range is [0 ,100)', range100,150)
frame.add_button('Range is [0 ,1000)', range1000,150)
frame.add_input('Enter a guess', input_guess, 150)


# call new_game and start frame
new_game()


# always remember to check your completed program against the grading rubric

OGDF GSoC Exercises 10


Problem Description

Write a program that

  1. generates a random series-parallel graph G (use OGDF’s generator, simply ignore the edge direction properties of the generated instance), and
  2. prints a readable description of how the edges/subgraphs can be combined via parallel or serial combinations, in order to obtain G.

E.g., the graph with the edges {ab,bd,ac,cd,ad} would give an output similar to (there are multiple possibilities):

1 := SER ab bd
2 := SER ac cd
3 := PAR 1 ad
G := PAR 3 2

(where the numbers just reference the lines where the corresponding subgraph was generated)

Find more details here.

Solution

/**
* This is the solution file for the Exercise 10
*
* @author Chameera Wijebandara
* @email chameerawijebandara@gmail.com
*
*	Windows 7
*	Vishual stuio 2010
*	OGDF Snapshot 2014-02-28
*
*/
#include <ogdf/basic/Graph.h>
#include <ogdf/fileformats/GraphIO.h>
#include <ogdf/basic/graph_generators.h>
#include <ogdf/layered/SugiyamaLayout.h>
#include <ogdf/layered/OptimalRanking.h>
#include <ogdf/layered/FastHierarchyLayout.h>
#include <ogdf/layered/BarycenterHeuristic.h>
#include <map>

using namespace ogdf;
using namespace std;

// main
int main()
{

	// init the new grapth
	Graph G;

	// genarate random series paralle grapth
	randomSeriesParallelDAG(G, 6);

	// set grapth attributes
	GraphAttributes GA(G,
		GraphAttributes::nodeGraphics | GraphAttributes::edgeGraphics |
		GraphAttributes::nodeLabel | GraphAttributes::edgeStyle |
		GraphAttributes::nodeStyle );

	//maper to map node id
	map<int, int> maper;
	int nodeCount=0;
	node v;
	forall_nodes( v, G ){	// iterate through all	the node in the graph

		GA.fillColor( v ) = Color( "#FFFF00" );	// set node color to yellow
		GA.height( v ) = 20.0;	// set the height to 20.0
		GA.width( v ) = 40.0;	// set the width to 40.0

		char id = (char)(nodeCount +'a');
		GA.label( v ) = id;

		maper.insert(make_pair(v->index(), nodeCount));
		nodeCount++;
	}

	SugiyamaLayout SL;	 //init the SugiyamaLayout algorithm
	SL.setRanking(new OptimalRanking);
	SL.setCrossMin(new BarycenterHeuristic);

	FastHierarchyLayout *fhl = new FastHierarchyLayout;
	fhl->layerDistance(40.0);	// set layer distance to 40.0
	fhl->nodeDistance(20.0);	// set node distance to 20.0.
	SL.setLayout(fhl);

	SL.call(GA);
	GraphIO::drawSVG(GA, "execrise10.svg");

	int n = G.numberOfNodes(); // get number of nodes
	int m = G.numberOfEdges(); // get number of edges

	if(n==1) // if grapth only contain 1 node
	{
		cout<<"G := a";
		return 0;
	}
	if(n==2) // if grapth only contain 3 node
	{
		cout<<"G := ab";
		return 0;
	}

	// init variblaes.
	int* begin =new int[m];
	int* end =new int[m];
	int* state =new int[m];

	// subgrapth index
	int count =1;
	int countHold=1;

	// collect edeg data
	edge e;
	forall_edges(e,G){
		int temp =e->index();
		begin[temp] = maper.find(e->source()->index())->second ;
		end[temp] = maper.find(e->target()->index())->second;
		state[temp] = 0;
	}

	// count digree of the each node.
	int* inCount = new int[n];
	int* outCount = new int[n];

	//go untill complete the graph
	do{
		countHold =count;

		//init digree vaiables
		for(int i=0; i<n; i++)
		{
			inCount[i]=0;
			outCount[i]=0;
		}

		// calculate current degree
		for(int i = 0; i < m; i++)
		{
			if(state[i]!=-1)
			{
				inCount[end[i]]++;
				outCount[begin[i]]++;
			}
		}

		// gothrough the each node
		for(int i=0;i<n;i++)
		{
			// chaeck for seriall part
			if(inCount[i] == 1 && outCount[i]==1)
			{
				// go througth every edge
				for(int j=0;j<m;j++)
				{
					// check for second edge
					if(begin[j]==i && state[j]!=-1)
					{
						for(int k=0;k<m;k++)
						{
							// chcheck edge is not used
							if(end[k]==i && state[k]!=-1 && j!=k)
							{
								int tempCount=0;
								for(int l=0;l<m;l++)
								{
									if(state[l]!=-1)
									{
										tempCount++;
										if(tempCount>2)
										{
											break;
										}
									}
								}

								// print the output
								if(tempCount>2)
								{
									cout<< count;
								}
								else
								{
									cout<<"G";
								}
								cout<<" := SER ";

								if(state[k]==0)
								{
									cout<<(char)('a'+begin[k])<<(char)('a'+ end[k]);
								}
								else
								{
									cout<<state[k];

								}
								cout<<" ";
								if(state[j]==0)
								{
									cout<<(char)('a'+begin[j])<<(char)('a'+end[j]);
								}
								else
								{
									cout<<state[j];

								}
								state[j] = -1;

								cout<<endl;

								// set new edge data
								state[k] = count;
								end[k] = end[j];
								count++;

								break;
							}
						}
						break;
					}
				}
			}
		}

		// chech for pararell part
		for(int i=0;i<m;i++)
		{
			for(int j=i+1;j<m;j++)
			{
				// chaech for the  same sorse and traget
				if(begin[i] ==begin[j] &&  end[i]&& end[j] && state[i]!=-1 && state[j]!=-1)
				{
					int tempCount =0;
					for(int k=0;k<m;k++)
					{

						if(state[k]!=-1)
						{
							tempCount++;
							if(tempCount>2)
							{
								break;
							}
						}
					}

					// print the output
					if(tempCount>2)
					{
						cout<< count;
					}
					else
					{
						cout<<"G";
					}
					cout<<" := PAR ";

					if(state[i]==0)
					{
						cout<<(char)('a'+end[i])<<(char)('a'+begin[i]);
					}
					else
					{
						cout<<state[i];
					}

					cout<<" ";

					if(state[j]==0)
					{
						cout<<(char)('a'+end[j])<<(char)('a'+begin[j]);
					}
					else
					{
						cout<<state[j];
					}
					cout<<endl;

					// set new edge data
					state[j] = -1;
					state[i] = count;
					count++;

					break;
				}
			}
		}

	}while(count != countHold);

	getchar();

	// delet alocated memory

	delete(begin);
	delete(end);
	delete(state);
	delete(inCount);
	delete(outCount);

}

Algorithm


do while( undiscovered edges )

	// Find serial parts
	Find node if(indeg ==1 && out outdeg==1)	// a -> b and b-> c
		Merge the sub graph // a -> c
		Print the sub graph details	 //  i := SER ab bc

	// Find Parallel parts
	Find edges which has same source and target  // a -> c  and a -> c
		Merge the sub graph // a -> c
		Print the sub graph details	 //  i := PAR 1 ac

	// State variable mange the state of the edge
	// -1 : finished
	//  0 : not yet discovered
	// >0 : already discovered( represent a sub graph)

Output

EX_10

OGDF GSoC Exercises 05


Problem Description

Compute the DFS-tree of a given graph, direct and color the edges according to the tree, and draw the resulting graph with a hierarchical layout algorithm. In particular, your program shall perform the following steps:

  1. Create a random undirected graph G using a suitable OGDF graph generator of your choice.
  2. Perform a depth-first search on G starting at a randomly selected vertex s, thereby computing the DFS-tree as well as the DFS-number of each node (this gives the order in which nodes are visited by the search).
  3. Direct the edges in G according to their DFS-number, so that they point from lower to higher number.
  4. Compute a hierarchical drawing of G (using SugiyamaLayout), coloring the edges of the DFS-tree with red and the other edges with blue, and write the drawing to an SVG file dfs.svg.

Find more details here.

Solution



/**
*This is the solution file for the Exercise 05
*
* @author Chameera Wijebandara
* @email chameerawijebandara@gmail.com
*
*	Windows 7
*	Vishual stuio 2010
*	OGDF Snapshot 2014-02-28
*
*/

#include <ogdf/basic/Graph.h>
#include <ogdf/fileformats/GraphIO.h>
#include <ogdf/basic/graph_generators.h>
#include <ogdf/layered/SugiyamaLayout.h>
#include <ogdf/layered/OptimalRanking.h>
#include <ogdf/layered/MedianHeuristic.h>
#include <ogdf/layered/OptimalHierarchyLayout.h>

using namespace ogdf;

bool createDFTree( const int n, const int m );
void dfs( GraphAttributes *GA, Graph *G , Array<int> *state , node *current );

// main 
int main()
{

	cout<<"Pleace enter number n (n>0) : ";
	int n,m;
	cin >> n;
	cout<<"Pleace enter number m (m>0) : ";
	cin >> m;

	createDFTree( n, m );

	return 0;
}
//end of the main

/*
Create a random undirected graph G using a suitable OGDF graph generator of your choice.
Perform a depth-first search on G starting at a randomly selected vertex s, thereby computing the DFS-tree as well as the DFS-number of each node (this gives the order in which nodes are visited by the search).
Direct the edges in G according to their DFS-number, so that they point from lower to higher number.
Compute a hierarchical drawing of G (using SugiyamaLayout), coloring the edges of the DFS-tree with red and the other edges with blue, and write the drawing to an SVG file dfs.svg.
*/

bool createDFTree( const int n, const int m )//number of nodes n and the number of edges m of the graph to be generated
{
	Graph G;
	randomSimpleGraph( G, n, m); // Create a random DAG using OGDF's random_hierarchy graph generator

	GraphAttributes GA( G, GraphAttributes::nodeGraphics |
		GraphAttributes::edgeGraphics |
		GraphAttributes::nodeLabel |
		GraphAttributes::nodeStyle |
		GraphAttributes::edgeType |
		GraphAttributes::edgeArrow |
		GraphAttributes::edgeStyle ); // Create graph attributes for this graph
	GA.setDirected(false); // set to undirected

	node v;
	forall_nodes( v, G ){	// iterate through all	the node in the graph
		GA.fillColor( v ) = Color( "#FFFF00" );	// set node color to yellow
		GA.height( v ) = 20.0;	// set the height to 20.0
		GA.width( v ) = 40.0;	// set the width to 40.0

		string s = to_string(v->index());	
		char const *pchar = s.c_str();  //use char const* as target type

		GA.label( v ) = pchar;
	}

	edge e;
	forall_edges(e ,G)	// set default edge color and type
	{
		GA.bends(e);
		GA.arrowType(e) =  ogdf::EdgeArrow::eaNone;
		GA.strokeColor(e) = Color("#0000FF");
	}

	Array<int> state(G.numberOfNodes()); // create state array to store the current states of the nodes	

	for(int i=0;i<state.size();i++)  
	{
		state[i] = -1;	// init the state vaiables
	}

	v = G.chooseNode();	 // select random nodes for source

	state[ v->index() ]=0;

	dfs( &GA, &G ,&state, &v); // start recurtion

	SugiyamaLayout SL;	 //Compute a hierarchical drawing of G (using SugiyamaLayout)
	SL.setRanking( new OptimalRanking );
	SL.setCrossMin( new MedianHeuristic );

	OptimalHierarchyLayout *ohl = new OptimalHierarchyLayout;
	ohl->layerDistance( 30.0 );
	ohl->nodeDistance( 25.0 );
	ohl->weightBalancing( 0.8 );
	SL.setLayout( ohl );
	SL.call( GA );

	GraphIO::drawSVG( GA, "dfs.svg" );

	return true;
}

void dfs( GraphAttributes *GA, Graph *G , Array<int> *state , node *current )
{
	edge e;
	forall_edges( e, *G ){	// iterate through all the node in the graph

		node u = e->target();
		if( e->source()->index() == (*current)->index() && (*state)[ u->index() ]==-1 )	 // 
		{	
			(*state)[ u->index() ]=0;	 // set states	

			GA->bends( e );
			GA->arrowType( e ) =  ogdf::EdgeArrow::eaLast;	 // add red colure and arrow type
			GA->strokeColor( e ) = Color( "#FF0000" );

			dfs( GA, G, state, &u );	
		}

		u = e->source();
		if( e->target()->index() == (*current)->index() && (*state)[ u->index() ]==-1)	 //
		{	
			(*state)[ u->index() ]=0;	 // set states	

			GA->bends( e );
			GA->arrowType( e ) =  ogdf::EdgeArrow::eaFirst;
			GA->strokeColor( e ) = Color( "#FF0000" );

			dfs( GA, G, state, &u );	
		}
	}
}

Output

EX_05