<file_sep>#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<pthread.h>
#include<semaphore.h>

int TA_Sleeping;

sem_t semTA;
sem_t chairs;
pthread_mutex_t Helpmutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t TAcreated = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t helping = PTHREAD_MUTEX_INITIALIZER;


void helpStudent(){
	while(1){
		int availableChairs;
		sem_getvalue(&chairs,&availableChairs);
		if(availableChairs == 3){TA_Sleeping = 1;printf("The TA is sleeping\n");}
		sem_wait(&semTA);
		sleep(2);
		pthread_mutex_unlock(&helping);
	}
}

void getHelp(long studentID){
	if(TA_Sleeping){
		TA_Sleeping = 0;
		printf("Student %lu woke up the TA\n",studentID);
		sem_post(&semTA);
		pthread_mutex_unlock(&Helpmutex);
		pthread_mutex_lock(&helping);
	}
	else{
		int availableChairs;
		sem_getvalue(&chairs,&availableChairs);
		if(availableChairs == 3){
			sem_wait(&chairs);
			printf("Student %lu took a seat in chair 1\n",studentID);
			pthread_mutex_unlock(&Helpmutex);
			sem_post(&semTA);
			pthread_mutex_lock(&helping);
			printf("TA is Helping a student %lu\n", studentID);
			sem_post(&chairs);		
			printf("Chair 1 is now open\n");
		}
		if(availableChairs == 2){
			sem_wait(&chairs);
			printf("Student %lu took a seat in chair 2\n",studentID);
			pthread_mutex_unlock(&Helpmutex);
			sem_post(&semTA);
			pthread_mutex_lock(&helping);
			printf("TA is Helping a student %lu\n", studentID);
			sem_post(&chairs);	
			printf("Chair 2 is now open\n");
		
		}
		if(availableChairs == 1){
			sem_wait(&chairs);
			printf("Student %lu took a seat in chair 3\n",studentID);
			pthread_mutex_unlock(&Helpmutex);
			sem_post(&semTA);
			pthread_mutex_lock(&helping);
			printf("TA is Helping a student %lu\n", studentID);
			sem_post(&chairs);	
			printf("Chair 3 is now open\n");		
		}
		if(availableChairs == 0){	printf("Student %lu went back to programming\n",studentID);
				pthread_mutex_unlock(&Helpmutex);}
	}
}



void *initTA(){
	sem_init(&semTA,0,0);
	sem_init(&chairs,0,3);
	TA_Sleeping = 1;
	pthread_mutex_unlock(&TAcreated);
	helpStudent();	
}
void *initStudent(void *t){
	pthread_mutex_lock(&Helpmutex);
	long id = (long)t;
	getHelp(id);
}

int main(int argc,char **argv){

	//Make n student threads
		int n = 6;
		int ret;
		//Make TA Thread
		
		
		pthread_mutex_lock(&TAcreated);
		pthread_t TA;
		ret = pthread_create(&TA,NULL,initTA,NULL);
		
		pthread_mutex_lock(&TAcreated);
		long t;
		pthread_t threads[n];
		for(t = 0; t<n;t++){
			ret = pthread_create(&threads[t],NULL,initStudent,(void *)t);
		}
		


	//Make threads wait for all to terminate before ending program
		for(t = 0; t<n;t++){
			pthread_join(threads[t],NULL);
		}
		pthread_join(TA,NULL);
	return 0;	
}
<file_sep>#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

int getInput(){
	printf("Enter a Positive Number: ");
	int num;
	scanf("%d", &num);
	if(num < 0){getInput();}
	else{return num;}
}
void collatz(int num){
	printf("%d", num);
	printf(" ");
	if(num > 1){	
		if(num%2 == 0){ num = num/2;}
		else{num = (3*num)+1;}
		collatz(num);
	}
	if(num == 1){printf("\n");}//Print a new line to make answer more readable
}

int main()
{
    int pid;
    pid=fork();
    int number;
    if(pid<0)
    {
        printf("\n Error ");
        exit(1);
    }
    else if(pid==0)
    {
	//This is the child process so make it do all the work
	number = getInput();
	collatz(number);
        exit(0);
    }
    else
    {
	//This is the parent process so make it wait for child to finish
	wait();        
        exit(1);
    }

}
<file_sep>#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdlib.h>
#define MAX_LINE 80



int main(void){
	int shouldWait = 0;
	int should_run = 1;
	char **hist = malloc(10*sizeof(char*));
	int commandcount = 0;
	//allocate the history array
	int k = 0;
	while(k < 10){
		hist[k] = malloc(MAX_LINE);
		strcpy(hist[k],"0");
		k++;
	}
	
	void addHistory(char* arg){
		int i = 0;
		while(i < 9){
			if(strcmp(hist[i+1],"0")!= 0){strcpy(hist[i],hist[i+1]);}
			i++;
		}	
		strcpy(hist[9],arg);
		commandcount++;
	}
	
	void history(){
		int i = 0;
		int count = 0;
		while(i < 10){
			if(strcmp(hist[i],"0")!= 0){
				printf("%d ", commandcount-count);
				printf("%s\n", hist[i]);
				count++;
			}
			i++;
		}
	}
	
	int runShell(){
		
		char *saveprt;
		char arg[MAX_LINE];
		char *temp;
		int argnum = 0;
		int i;
		char *tempargs[MAX_LINE/2 +1];
		char **args;
		pid_t pid;
		shouldWait = 0;
		
		printf("osh>");
		fflush(stdout);
		fflush(stdin);
		fgets(arg,MAX_LINE,stdin);
		strtok_r(arg,"\n",&saveprt);
		if(strcmp(arg,"history")!= 0 && strcmp(arg,"\n")!= 0 && arg[0]!= '!'){addHistory(arg);}
		if(arg[0] == '!'){	if(arg[1] == '!'){
								if(strcmp(hist[9],"0")!= 0){strcpy(arg,hist[9]);}
								else{printf("No commands in history\n");}}
						  	else{
								char *end;
								int n = strtol(&arg[1],&end,10);
								if(0 < n && n <= 10){
								if(strcmp(hist[10-n],"0")!= 0){strcpy(arg,hist[10-n]);}
								else{printf("No such command in history\n");}}
								else{printf("No such command in history\n");}
							}
							
		}
		temp = strtok_r(arg," ",&saveprt);
		i = 0;
		while(temp != NULL){
			tempargs[i] = temp;
			i++;
			argnum++;
			temp = strtok_r(NULL," ",&saveprt);
		}

		i = 0;
		if(strcmp(tempargs[argnum-1],"&") == 0){		
			shouldWait = 1;
			argnum --;
			args = malloc(argnum*sizeof(char*));
			while(i < argnum){	
				args[i] = malloc(MAX_LINE);
				strcpy(args[i],tempargs[i]);	
				i++;
			}
		}
		else{
			args = malloc(argnum*sizeof(char*));
			while(i < argnum){	
				args[i] = malloc(MAX_LINE);
				strcpy(args[i],tempargs[i]);	
				i++;
			}
		}	

		if(strcmp(args[0],"exit")==0){return 0;}
		else if(strcmp(args[0],"history")==0){history();free(args);runShell();}
		else{
			fflush(stdout);
			int status;
			pid = fork();
			if(pid<0){printf("Error in fork"); return 1;}
			else if(pid == 0){execvp(args[0],args);return 0;}
			else 	if(shouldWait){wait(&status);free(args);runShell();}
					else{free(args);runShell();}
		}
		

	}
	int run = runShell();
	free(hist);
	return run;
}

<file_sep>#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<pthread.h>
#define MAX_RESOURCES 100

int numThreads = 1;
int available_resources = MAX_RESOURCES;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t resc_thresh;

void waitForResources(int resc){
	while(resc > available_resources){
		sleep(.5);
	}
}

//Part A of the code
int decrease_count(int count,long t){
	if(available_resources < count){
		printf("XXXXXXX Insufficient Resources for thread %lu\n",t);
		printf("XXXXXXX Tried to claim %d resources\n", count);
		printf("XXXXXXX Available: %d\n\n", available_resources);
		return -1;
	}
	else{
		available_resources -= count;
		printf("Thread %lu claimed %d resources\n",t,count);
		printf("Claimed: %d resources\n", count);
		printf("Available: %d\n", available_resources);
		
		return 0;
	}
}
int increase_count(int count,long t){
	available_resources += count;
	printf("Thread %lu added %d resources\n",t,count);
	printf("There are now %d resources available\n\n\n",available_resources);
	return 0;
}


void *getResources(void *t){
	long threadID = (long)t;
	int resc = rand()%100;
	if(resc > MAX_RESOURCES){
		printf("Thread %lu attempted to claim more than max resources.\n",threadID);
	}
	else{
		int success = decrease_count(resc,threadID);
		if(success == 0){increase_count(resc,threadID);}
	}
	pthread_exit(0);
}



//This is the code where the monitor is implemented
//Part C of the code
void decrease_countMonitor(int resc,long t){
	pthread_mutex_lock(&mutex);
	if(available_resources < resc){
		printf("Thread %lu WAITING to claim %d resources\n\n",t, resc);
		pthread_cond_wait(&resc_thresh, &mutex);
	}
	available_resources -= resc;
	printf("Thread %lu\n",t);
	printf("Claimed: %d resources\n", resc);
	printf("Available: %d\n\n\n", available_resources);
	pthread_mutex_unlock(&mutex);
}

void increase_countMonitor(int resc, long t){
	pthread_mutex_lock(&mutex);
	available_resources += resc;
	printf("Thread %lu added %d resources\n",t,resc);
	printf("There are now %d resources available\n\n\n",available_resources);
	pthread_cond_signal(&resc_thresh);
	pthread_mutex_unlock(&mutex);
}


void *getResourcesMonitor(void *t){
	long threadID = (long)t;
	int resc = rand()%10+90;
	if(resc > MAX_RESOURCES){
		printf("Thread %lu attempted to claim more than max resources.\n",threadID);
	}
	else{
		decrease_countMonitor(resc,threadID);
		increase_countMonitor(resc,threadID);
	}
	pthread_exit(0);
}


	
	
	
	
	
	
	
	
	
	
	
int main(int argc, char *argv[])
{
	numThreads = atoi(argv[1]);
	printf("Enter A to see race condition or M to see the Monitor: ");
	char condition[80];
	fgets(condition,80,stdin);
	printf("%s",condition);

	//Make all the threads
	pthread_cond_init(&resc_thresh,NULL);
	pthread_t threads[numThreads];
	int ret;
	long t;
	
	if(strcmp(condition,"A\n") == 0 || strcmp(condition,"a\n") == 0){
		printf("RACE CONDITION:\n");
		for(t = 0; t<numThreads;t++){
			ret = pthread_create(&threads[t],NULL,getResources,(void *)t);
		}

		//Make threads wait for all to terminate before ending program
		for(t = 0; t<numThreads;t++){
			pthread_join(threads[t],NULL);
		}
	}
	else{
		if(strcmp(condition,"M\n") == 0 || strcmp(condition,"m\n") == 0){
			printf("Monitor\n");
			for(t = 0; t<numThreads;t++){
				ret = pthread_create(&threads[t],NULL,getResourcesMonitor,(void *)t);
			}

			//Make threads wait for all to terminate before ending program
			for(t = 0; t<numThreads;t++){
				pthread_join(threads[t],NULL);
			}
		}
	}
	pthread_exit(NULL);
}
<file_sep>#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>

long numAdds = 0; 
int *page;
int *offset;
long *pageTable;
long* physical;
int pageFault = 1;
int tlbHits = 0;
long **tlb;

long checkTlb(int index){
	int i;
	for(i = 0;i < 16; i++){
		if(tlb[i][0] == page[index]){;
			return tlb[i][1];
		}
	}
	
	return (long)2;
}

void addTlb(int index){
	int i;
	for(i = 1;i < 16; i++){
		tlb[i-1][0] = tlb[i][0];
		tlb[i-1][1] = tlb[i][1];
	}
	tlb[15][0] = page[index];
	tlb[15][1] = pageTable[page[index]];
}

void getPhysical(long *logicals){
	physical = malloc(sizeof(long)*1000);
	int i;
	long frame = 0;
	for(i = 0;i<numAdds;i++){
		int off = offset[i];
		long isTlb = checkTlb(i);
		if(isTlb == 2){	
			if(pageTable[page[i]] == 1){
				pageTable[page[i]] = frame; 
				frame += 256;
				pageFault++;
			}
			physical[i] = pageTable[page[i]] + off;
			addTlb(i);
		}
		else{physical[i] = isTlb + off;tlbHits++;}
		
	}
}

int isFreeFrame(){
	int i;
	for(i = 0;i < 128;i++){
		if(pageTable[i] == 1){return i;}
	}
	return 0;
}

int findVictim(){
	int i;
	for(i = 0; i < 128; i++){
		int intlb = 0;
		int j;
		for(j = 0; j < 16; j++){
			if(tlb[j][0] == i){intlb = 1;}
		}
		if(!intlb){return i;}
	}
}
void getPhysicalMod(long *logicals){
	physical = malloc(sizeof(long)*1000);
	int i;
	long frame = 0;
	for(i = 0;i<numAdds;i++){
		int off = offset[i];
		long isTlb = checkTlb(i);
		if(isTlb == 2){	
			if(pageTable[page[i]] == 1){
				pageTable[page[i]] = frame; 
				frame += 128;
				pageFault++;
			}
			else{
				
				int freeFrame = isFreeFrame();
				//Use a free frame if available
				if(freeFrame>0){
					pageTable[freeFrame] = frame;
					frame += 128;
					pageFault++;
				}
				//If no free frame find first frame no in use by tlb and make it victim
				else{
					int victim = findVictim();	
					pageTable[victim] = frame;
					frame += 128;
					pageFault++;
				}
			}
			physical[i] = pageTable[page[i]] + off;
			addTlb(i);
		}
		
		else{physical[i] = isTlb + off;tlbHits++;}
		
	}
}

void initPageTable(){
	pageTable = malloc(256*sizeof(long));
	int i;
	pageTable[0] = 0;
	for(i = 1; i < 256;i++){
		pageTable[i] = 1;
	}
	tlb = malloc(sizeof(long)*16);
	for(i = 0;i < 16;i++){
		tlb[i] = malloc(2*sizeof(long));
		tlb[i][0] = 256;
		tlb[i][1] = 0;
	}
}

void toDec(int *bin,int index){
	int dec = 0;
	int i;
	int pow = 1;
	for(i = 15;i >= 0;i--){
		if(i >7){
			if(bin[i] == 1){
				dec += pow;
			}
			pow = pow*2;
		}
		if(i == 7){pow = 1; offset[index] = dec; dec = 0;}
		if(i <= 7){
			if(bin[i] == 1){
				dec += pow;
			}
			pow = pow*2;
		}
	}	
	page[index] = dec;
}

void toBinary(long *adds){
	int i;
	page = malloc(sizeof(long)*numAdds);
	offset = malloc(sizeof(long)*numAdds);

	for( i = 0; i < numAdds; i++){
		long num = adds[i];
		int index = 15;
		int b[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
		while(num != 0){
			b[index] = num%2;
			num = num/2;
			index -= 1;
		}
		toDec(b,i);

	}
}

long * openFile(char* filename){
	//Open file
	FILE *fp;
	fp = fopen(filename,"r");
	long *addresses = malloc(sizeof(long)*1000);
	if(fp==NULL){printf("File not found.\n");}
	else{

		int i = 0;
		char ch;
		char l[5];
		int j = 0;
		while((ch = fgetc(fp))!= EOF){
			if(ch == '\n'){
				j = 0;
				addresses[i] = atoll(l);
				numAdds++;
				i++;
				int k;
				for(k = 0;k<5;k++){
					l[k] = 0;
				}
			}
			else{l[j] = ch;j++;}
		}
	}
	return addresses;
}

int main(int argc,char *argv[]){
	//Get Command Line Args
	char* addresses = argv[1];
	//Prompt for Mod
	printf("Input '1' for Modifications and '0' for No Modifications: ");
	char input[80];
	fgets(input,80,stdin);
	int mod = atoi(input);
	if(mod == 1){mod = 1;}
	//Open file and read addresses
	long *logicals = openFile(addresses);
	toBinary(logicals);
	initPageTable();
	if(mod){getPhysicalMod(logicals);}
	else{getPhysical(logicals);}
	//Print out logical addresses
	int i;
	for(i = 0; i < numAdds;i++){
		printf("Virtual address: %lu ",logicals[i]);
		printf("Physical address: %lu ",physical[i]);
		printf("Value: %d",*((signed char *)&physical[i]));
		printf("\n");
		
	}
	printf("Number of Translated Addresses = %lu\n",numAdds);
	printf("Page Faults = %d\n",pageFault);
	printf("Page Fault Rate = %g\n", (double)pageFault/(double)numAdds);
	printf("TLB Hits = %d\n",tlbHits);
	printf("TLB Hit Rate = %g\n", (double)tlbHits/(double)numAdds);
	return 0;
}
<file_sep>#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<pthread.h>
#include<semaphore.h>
#include<time.h>

//Initialize exit variable to quit threads
int shouldExit = 0;

//Define Semaphores and Mutexes
sem_t empty;
sem_t full;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;;

//Define Buffer
typedef int buffer_item;
#define BUFFER_SIZE 5
buffer_item buffer[BUFFER_SIZE];


void initBuffer(){
	printf("Setting up buffer....\n");
	sleep(0);
	//buffer = (buffer_item [5]);
	printf("Buffer Initialized\n");
}

int insert_item(buffer_item item,long id){
	int success = 0;
	//Insert item into buffer
	//Wait for something to be consumed
	printf("Producer thread %lu waiting for empty spot in buffer\n",id);
	sem_wait(&empty);
	pthread_mutex_lock(&mutex);
	printf("Producer thread %lu has lock on empty spot in buffer\n",id);
	int emptySpots = 0;
	sem_getvalue(&empty,&emptySpots);
	buffer[emptySpots] = item;
	pthread_mutex_unlock(&mutex);
	sem_post(&full);
	success = 1;
	
	if(success){return 1;}
	else{return 0;}
}

int remove_item(buffer_item *item,long id){
	int success = 0;
	//Remove Item from buffer
	//Wait for something to be produced
	printf("Consumer thread %lu waiting for production to finish\n",id);
	sem_wait(&full);
	pthread_mutex_lock(&mutex);
	printf("Consumer thread %lu has a lock on an item for consumption\n",id);
	int fullSpots = 0;
	sem_getvalue(&full,&fullSpots);
	*item = buffer[BUFFER_SIZE - fullSpots - 1];
	buffer[BUFFER_SIZE - fullSpots-1] = 0;
	pthread_mutex_unlock(&mutex);
	sem_post(&empty);
	success = 1;
	
	if(success){return 1;}
	else{return 0;}
}	

void *initProducer(void *t){
	buffer_item item = 0;
	long id = (long)t;
	while(1){
		if(shouldExit){pthread_exit(0);}
		//Sleep random period of time
		sleep(rand()%3);
		//Genereate random number for item size
		int temp = rand();
		item = temp;
		//Insert and item
		if(insert_item(item,id)){printf("Production Successful for thread %lu\n\n\n",id);}
		else{printf("Error in production on thread %lu\n",id);}
	}
}
void *initConsumer(void *t){
	buffer_item item = 0;
	long id = (long)t;
	while(1){
		if(shouldExit){pthread_exit(0);}
		//Sleep random period of time
		sleep(rand()%3);
		//Remove an item
		if(remove_item(&item,id)){printf("Consumer consumed %d on thread %lu\n\n\n",item,id);}
		else{printf("Error in consumption on thread %lu\n",id);}
	}
}

int main(int argc,char *argv[]){
	//Get Command Line Args
	int sleepTime = atoi(argv[1]);
	int pThreads = atoi(argv[2]);
	int cThreads = atoi(argv[3]);
	//Initialize Buffer
	initBuffer();

	//Initialize Semaphores and Mutexes
	sem_init(&empty,0,5);
	sem_init(&full,0,0);
	pthread_mutex_init(&mutex,NULL);

	
	//Make Consumer and Producer Threads
	pthread_t consumerThreads[cThreads];
	pthread_t producerThreads[pThreads];
	long t;
	int ret;
	for(t = 0; t<cThreads;t++){
		ret = pthread_create(&consumerThreads[t],NULL,initConsumer,(void *)t);
	}
	for(t = 0; t<pThreads;t++){
		ret = pthread_create(&producerThreads[t],NULL,initProducer,(void *)t);
	}
	
	
	/*
	//Join Threads at the end
		for(t = 0; t<cThreads;t++){
		pthread_join(consumerThreads[t],NULL);
	}
	for(t = 0; t<pThreads;t++){
		pthread_join(producerThreads[t],NULL);
	}*/
	
	
	//Sleep before terminating
	sleep(sleepTime);
	shouldExit = 1;
	
	return 0;	
}
<file_sep>#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<pthread.h>
#define MAX_RESOURCES 6

int numThreads = 10;
int resc = 6;
int available_resources = MAX_RESOURCES;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int decrease_count(int count,long t){
	if(available_resources < count){printf("Insufficient Resources for thread %lu\n",t);return -1;}
	else{available_resources -= count; printf("Thread %lu claimed some resources\n",t); return 0;}
}
int increase_count(int count,long t){
	available_resources += count;
	return 0;
}

int decrease_countFixed(int count,long t){
	if(available_resources < count){printf("Insufficient Resources for thread %lu\n",t);return -1;}
	else{available_resources -= count; printf("Thread %lu claimed some resources\n",t); return 0;}
}
int increase_countFixed(int count,long t){
	available_resources += count;
	return 0;
}


void *getResources(void *t){
	long threadID = (long)t;
	if(resc > MAX_RESOURCES){printf("Thread %lu attempted to claim more than max resources.\n",threadID);}
	else{
		decrease_count(resc,threadID);
		increase_count(resc,threadID);
	}
	pthread_exit(0);
}

void *getResourcesFixed(void *t){
	long threadID = (long)t;
	pthread_mutex_lock(&mutex);
	if(resc > MAX_RESOURCES){printf("Thread %lu attempted to claim more than max resources.\n",threadID);}
	else{
		decrease_countFixed(resc,threadID);
		increase_countFixed(resc,threadID);
	}
	pthread_mutex_unlock(&mutex);
	pthread_exit(0);
}

int main()
{
	//Make all the threads
	pthread_t threads[numThreads];
	int ret;
	long t;
	printf("RACE CONDITION:\n");
	for(t = 0; t<numThreads;t++){
		ret = pthread_create(&threads[t],NULL,getResources,(void *)t);
	}
	
	//Make threads wait for all to terminate before ending program
	for(t = 0; t<numThreads;t++){
		pthread_join(threads[t],NULL);
	}
	
	printf("FIXED RACE CONDITION\n");
	for(t = 0; t<numThreads;t++){
		ret = pthread_create(&threads[t],NULL,getResourcesFixed,(void *)t);
	}
	
	//Make threads wait for all to terminate before ending program
	for(t = 0; t<numThreads;t++){
		pthread_join(threads[t],NULL);
	}
		
	pthread_exit(NULL);
}
<file_sep>#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>


int *unsorted;
int *sorted;
int lines;
int half;
int odd;

int compare( const void* a, const void* b)
{
     int int_a = * ( (int*) a );
     int int_b = * ( (int*) b );

     if ( int_a == int_b ) return 0;
     else if ( int_a < int_b ) return -1;
     else return 1;
}

void *sortFirstHalf(){
	int i;
	int temp1[half];
	for(i = 0;i < half;i++){
		memcpy(&temp1[i],&unsorted[i],sizeof(unsorted[i]));
	}
	qsort(temp1,half,sizeof(int),compare);
	for(i = 0;i < half;i++){
		memcpy(&unsorted[i],&temp1[i],sizeof(unsorted[i]));
	}												
	pthread_exit(0);
					}
void *sortSecondHalf(){
	int i;
	int temp2[half];
	for(i = 0;i < half-odd;i++){
		memcpy(&temp2[i],&unsorted[i+half],sizeof(unsorted[i+half]));
		
	}
	qsort(temp2,half,sizeof(int),compare);
	for(i = odd;i < half;i++){
		memcpy(&unsorted[i+half-odd],&temp2[i],sizeof(unsorted[i+half]));
	}
	pthread_exit(0);
					}
void *merge(){
	int i = 0;
	int j = 0;
	int k = half;
	while(i < lines){
		int a = 99999999;//Init to infinity as our "null" value
		int b = 99999999;
		if(j < half){a = unsorted[j];}
		if(k < lines){b = unsorted[k];}
		if(a <= b){j++; memcpy(&sorted[i],&a,sizeof(a));}
		else{k++; memcpy(&sorted[i],&b,sizeof(b));}
		i++;
	}
	pthread_exit(0);	
}


int main(int argc,char **argv){
	

	char buff[255];
	
	//read in file as a list
	//count lines
	FILE *fp;
	fp = fopen(argv[1],"r");
	fscanf(fp,"%s",buff);
	lines = 0;
	while(fgets(buff,255,(FILE*)fp)){
		lines++;
	}
	fclose(fp);
	
	//Allocate array and read in ints
	unsorted = (int*)calloc(lines, sizeof(int));
	sorted = (int*)calloc(lines,sizeof(int));
	fp = fopen(argv[1],"r");
	int i;
	for(i = 0; i < lines; i++){
		fscanf(fp,"%d",&unsorted[i]);
	}
	
	//split array into 2 arrays	
	if(lines%2 == 0){half = lines/2; odd = 0;}
	else{half = (lines+1)/2; odd = 1;}

	
	//Make 2 thread and assign a half on unsorted to be sorted in each thread
	//sort each list in its own sorting thread
	pthread_t tid1; //identifier
	pthread_attr_t attr1; //attributes
	
	pthread_attr_init(&attr1); //get default attributes
	pthread_create(&tid1,&attr1,sortFirstHalf,NULL);
	
	pthread_t tid2; //identifier 2
	pthread_attr_t attr2; //attributes 2
	
	pthread_attr_init(&attr2); //get default attributes
	pthread_create(&tid2,&attr2,sortSecondHalf,NULL);
	
	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);
	
	
	//merge lists in a merge thread
	for(i = 0; i < lines; i++){
		//printf("%d\n",unsorted[i]);
	}
	pthread_t tid3; //identifier 2
	pthread_attr_t attr3; //attributes 2
	
	pthread_attr_init(&attr3); //get default attributes
	pthread_create(&tid3,&attr3,merge,NULL);

	pthread_join(tid3,NULL);
	
	//merge lists in a merge thread
	printf("Sorted Array: [");
	for(i = 0; i < lines; i++){
		if(i < lines-1){printf("%d,",sorted[i]);}
		else{printf("%d]\n",sorted[i]);}
	}
	free(sorted);
	free(unsorted);
	return 0;
}	

