Question: // Enzyme Project for C Computer Operating Systems /* --QUESTIONS-- 1) Briefly explain why this application would be difficult to write using multiple processes instead

// Enzyme Project for C Computer Operating Systems

/*

--QUESTIONS--

1) Briefly explain why this application would be difficult to write using multiple processes instead of threads.

2) What is the significance of 'workperformed'? How is it used?

3) Explain exactly what is the type of 'fp' in the following declaration: void *(*fp

--MODIFICATIONS--

1) The function run_enzyme() needs to be created. Please see the notes inside within the program (see below).

2) The function 'make_enzyme_threads' has a memory bug. Fix this by simply re-ordering the lines in this function. It is simple fix but may take a while for you to find it.

3) The function 'join_on_enzymes' is incomplete. Insert the correct code snippets into 'whatgoeshere'.

--QUESTIONS--

1)What do we not detach any of the enzyme threads? Would the program function if we detach the sleeper thread?

2) Why does the program use sched_yield? What happens if this is not used? Will the swap counts always be identical?

3) Threads are canceled if the string contains a 'C' eg "Cherub". Why do we not include canceled threads when adding up the total number of swaps?

4) What happens when a thread tries to join itself? (You may need to create a test program to try this) Does it deadlock? Or does it generate an error?

5) Briefly explain how the sleeper thread is implemented.

6) Briefly explain why PTHREAD_CANCEL_ASYNCHRONOUS is used in this MP.

7) Briefly explain the bug in #2 of the above section.

*/

#include "enzyme.h"

int please_quit;

int use_yield;

int workperformed;

// The code each enzyme executes.

void *run_enzyme(void *data) {

/* This function should :

1. cast the void* pointer to thread_info_t*

2. initialize the swapcount to zero

3. Set the cancel type to PTHREAD_CANCEL_ASYNCHRONOUS

4. If the first letter of the string is a C then call pthread_cancel on this thread.

5. Create a while loop that only exits when please_quit is nonzero

6. Within this loop: if the first character of the string has an ascii value greater than the second (s[0] >s[1]) then -

Set workperformed=1, increment swapcount for this thread, then swap the two characters around

If "use_yield" is nonzero then call pthread_yield at the end of the loop.

7. Return a pointer to the updated structure.

*/

while(0) {

sched_yield();

};

return NULL;

}

// Make threads to sort string.

// Returns the number of threads created.

// There is a memory bug in this function.

int make_enzyme_threads(pthread_t * enzymes, char *string, void *(*fp)(void *)) {

int i,rv,len;

thread_info_t *info;

len = strlen(string);

info = (thread_info_t *)malloc(sizeof(thread_info_t));

for(i=0;i

info->string = string+i;

rv = pthread_create(enzymes+i,NULL,fp,info);

if (rv) {

fprintf(stderr,"Could not create thread %d : %s ",

i,strerror(rv));

exit(1);

}

}

return len-1;

}

// Join all threads at the end.

// Returns the total number of swaps.

int join_on_enzymes(pthread_t *threads, int n) {

int i;

int totalswapcount = 0;

int whatgoeshere=0; // just to make the code compile

// you will need to edit the code below

for(i=0;i

void *status;

int rv = pthread_join(threads[i],&status);

if(whatgoeshere) {

fprintf(stderr,"Can't join thread %d:%s. ",i,strerror(rv));

continue;

}

if ((void*)whatgoeshere == PTHREAD_CANCELED) {

continue;

} else if (status == NULL) {

printf("Thread %d did not return anything ",i);

} else {

printf("Thread %d exited normally: ",i);// Don't change this line

int threadswapcount = whatgoeshere;

// Hint - you will need to cast something.

printf("%d swaps. ",threadswapcount); // Don't change this line

totalswapcount += threadswapcount;// Don't change this line

}

}

return totalswapcount;

}

/* Wait until the string is in order. Note, we need the workperformed flag just in case a thread is in the middle of swapping characters

so that the string temporarily is in order because the swap is not complete.

*/

void wait_till_done(char *string, int n) {

int i;

while(1) {

sched_yield();

workperformed=0;

for(i=0;i

if (string[i] > string[i+1]) {

workperformed=1;

}

if(workperformed==0) break;

}

}

void * sleeper_func(void *p) {

sleep( (int) p);

// Actually this may return before p seconds because of signals.

// See man sleep for more information

printf("sleeper func woke up - exiting the program ");

exit(1);

}

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

pthread_t enzymes[MAX];

int n,totalswap;

char string[MAX];

if (argc <= 1) {

fprintf(stderr,"Usage: %s ",argv[0]);

exit(1);

}

strncpy(string,argv[1],MAX); // Why is this necessary? Why cant we give argv[1] directly to the thread functions?

please_quit = 0;

use_yield =1;

printf("Creating threads... ");

n = make_enzyme_threads(enzymes,string,run_enzyme);

printf("Done creating %d threads. ",n);

pthread_t sleeperid;

pthread_create(&sleeperid,NULL,sleeper_func,(void*)5);

wait_till_done(string,n);

please_quit = 1;

printf("Joining threads... ");

totalswap = join_on_enzymes(enzymes, n);

printf("Total: %d swaps ",totalswap);

printf("Sorted string: %s ",string);

exit(0);

}

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!