Question

In: Computer Science

The function 'make_enzyme_threads' has a memory bug. Fix this by simply re-ordering the lines in this...

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. As a hint, you may want to pay attention to the addresses of the pointers that are passed to the individual enzymes

#include "enzyme.h"

int please_quit;
int use_yield;
int workperformed;

// The code executed by each enzyme.
void *run_enzyme(void *data) {
/* This function should :
1. Cast the void* pointer to thread_info_t* (defined in enzyme.h)*/

   thread_info_t *inp;

   inp = (thread_info_t *)(data);

/*2. Initialize the swapcount to zero*/

   int swapcount = 0;

/*3. Set the cancel type to PTHREAD_CANCEL_ASYNCHRONOUS (see pthread_setcanceltype)*/

   void *cancel_type = PTHREAD_CANCEL_ASYNCHRONOUS;

/*4. If the first letter of the string is a C then call pthread_cancel on this thread.
(see also, pthread_self)
Note, depeneding on your platform (and specifically for macOS) you have
to replace the call to pthread_cancel with
pthread_exit(PTHREAD_CANCELED) in order to make the cancel test
pass.*/

   if (s[0]) == 'C')

       pthread_cancel(pthread_self());

/*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 (info->string[0] > info->string[1]) then
- Set workperformed = 1
- Increment swapcount for this thread
- Swap the two characters around
7. If "use_yield" is nonzero then call pthread_yield at the end of the loop.
8. Return a pointer to the updated structure.
*/
       while (please_quit == 0) {

           if (s[0] >s[1]) {

               workperformed = 1;
               threadswapcount++;
               char c;
               c = s[0];
               s[0] = s[1];
               s[1] = c;

           }

           if (use_yield != 0)

               pthread_yield(pthread_self());

       }
while(0) {
pthread_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 < len - 1; i++) {
info->string = string + i;
rv = pthread_create(enzymes + i, NULL, fp, info);
if (rv) {
fprintf(stderr,"Could not create thread %d : %s\n", 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;


   //initialize the cancelled count
   int cancelcount = 0; // just to make the code compile

                       // you will need to edit the code below

   for (i = 0; i<n; i++) {

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


       /*if join status is non zero, then cant join the threads
       Thus the condition is to check whether rv estimated
       Above has a non zero value*/
       if (rv != 0)
       {

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

       //if status is PTHREAD_CANCELED
       if ((void*)status == PTHREAD_CANCELED)
       {
           //increment the cancelled count
           cancelcount++;
           continue;
       }

       else if (status == NULL)
       {
           printf("Thread %d did not return anything\n", i);
       }

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

                                                   //need to cast the status with thread_info_t
                                                   //and then get the swap count as thread swap count
           int threadswapcount = (thread_info_t *)status->swapcount;

           // Hint - you will need to cast something.
           printf("%d swaps.\n", 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) {
pthread_yield();
workperformed = 0;
for (i = 0; i < n; 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\n");
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 <word>\n",argv[0]);
exit(1);
}

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

please_quit = 0;
use_yield = 1;

printf("Creating threads...\n");
n = make_enzyme_threads(enzymes, string, run_enzyme);
printf("Done creating %d threads.\n",n);

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

wait_till_done(string, n);
please_quit = 1;
printf("Joining threads...\n");
totalswap = join_on_enzymes(enzymes, n);
printf("Total: %d swaps\n", totalswap);
printf("Sorted string: %s\n", string);

exit(0);
}

Solutions

Expert Solution

Fixed Code:

#include "enzyme.h"

int please_quit;
int use_yield;
int workperformed;

// The code which each enzyme execute.
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<len-1;i++) {
   info->string = string+i;
   rv = pthread_create(enzymes+i,NULL,fp,info);
   if (rv) {
   fprintf(stderr,"Could not create thread %d : %s\n",
           i,strerror(rv));
       exit(1);
   }
   }
   return len-1;
}


// Joins all threads at the end.
// Return 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
   // we will need to edit the code below
   for(i=0;i<n;i++) {
   void *status;
   int rv = pthread_join(threads[i],&status);

if(whatgoeshere) {
   fprintf(stderr,"Can't join thread %d:%s.\n",i,strerror(rv));
   continue;
   }

   if ((void*)whatgoeshere == PTHREAD_CANCELED) {
   continue;
   } else if (status == NULL) {
   printf("Thread %d did not return anything\n",i);
   } else {
   printf("Thread %d exited normally: ",i);// Don't change this line
   int threadswapcount = whatgoeshere;
   // Hint - we will need to cast something here.
   printf("%d swaps.\n",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 character so that the string temporarily is in order because the swap has not been completed.
*/
void wait_till_done(char *string, int n) {
   int i;
   while(1) {
   sched_yield();
   workperformed=0;
   for(i=0;i<n;i++)
   if (string[i] > string[i+1]) {
   workperformed=1;
       }
   if(workperformed==0) break;
   }
}

void * sleeper_func(void *p) {
   sleep( (int) p);
   // This may return before p second because of signal.
   // See man sleep for more information
   printf("sleeper func raised up - exiting the program \n");
   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 <word>\n",argv[0]);
   exit(1);
   }
   strncpy(string,argv[1],MAX); // Why is it necessary? Why cant we give argv[1] directly to thread function?

   please_quit = 0;
   use_yield =1;
  
   printf("Creating thread...\n");
   n = make_enzyme_threads(enzymes,string,run_enzyme);
   printf("Done creating %d thread\n",n);
   pthread_t sleeperid;
   pthread_create(&sleeperid,NULL,sleeper_func,(void*)5);

wait_till_done(string,n);
   please_quit = 1;
   printf("Joining thread...\n");
   totalswap = join_on_enzymes(enzymes, n);
   printf("Total: %d swap \n",totalswap);
   printf("Sorted string: %s\n",string);
  
   exit(0);
}


Related Solutions

C Language - The function 'make_enzyme_threads' has a memory bug. Fix this by simply re-ordering the...
C Language - 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. As a hint, you may want to pay attention to the addresses of the pointers that are passed to the individual enzymes. //enzyme.h contents //Note I could not use tag openers in the includes. #define _GNU_SOURCE #include (pthread.h) #include (stdio.h) #include (sys/types.h) #include (string.h) #include (stdlib.h)...
If the system bug fix is a contractual obligation, can the system bug fix be treated...
If the system bug fix is a contractual obligation, can the system bug fix be treated as an assurance warranty? Can it be seen as a separate performance obligation?
a) Which lines of code contain operations that change the contents of memory in this program?...
a) Which lines of code contain operations that change the contents of memory in this program? b) What are those operations? int main ( void ){             double dScore1;             double dScore2;             double dScore3;             double dAverage;             printf("Enter score 1: ");                                             //line 1             scanf("%lg", &dScore1);                                           //line 2             printf("Enter score 2: ");                                             //line 3             scanf("%lg", &dScore2);                                           //line 4             printf("Enter score 3: ");                                             //line 5             scanf("%lg", &dScore3);                                           //line 6             dAverage = (dScore1 + dScore2...
In C++, Implement the heapafication operation. Do not re-implement the binary tree class. Simply create a...
In C++, Implement the heapafication operation. Do not re-implement the binary tree class. Simply create a funcntion that takes in a binary tree and heapafies it. Meaning it takes in a pointer to a binary tree and converts it into a heap. (You may choose max or min heap).
A firm has been ordering on the basis of EOQ for a product that has an...
A firm has been ordering on the basis of EOQ for a product that has an annual requirement of 22,000 units/year and the unit cost is $40/unit. Ordering and receiving costs are $75/order, and the annual carrying costs are 30% of the part value in storage. The supplier is offering a 5% price discount on orders greater than 800 units/order. Determine the EOQ without considering the quanitity discount What is the total annual cost including the value of the product...
polymer that doesn't have memory what polymer has no memory
polymer that doesn't have memory what polymer has no memory
Q3. A study tested whether working Sudoku puzzles daily improved memory function in older adults. Memory...
Q3. A study tested whether working Sudoku puzzles daily improved memory function in older adults. Memory tests were performed before the study began, at 4 and 8 weeks. Using the information in the table below answering the following questions. State the null and alternate hypotheses. What is the total sample size? Identify the independent and dependent variables What is the test statistic value? What is the p value? What is your conclusion (assume α = .05)? What is the effect...
this is a test program foo that has a bug. Assume your machine has 4KB pages....
this is a test program foo that has a bug. Assume your machine has 4KB pages. Note that this code is runnable on a Linux machine. #include <stdlib.h> #include <stdio.h> #include <sys/mman.h> struct foo {     int a; // 4-byte int     int b; // 4-byte int }; int main (int argc, char * argv[]) {     int num = atoi(argv[1]); // convert program arg to integer     struct foo * a = mmap(NULL,                           sizeof(struct foo) * num,                           PROT_READ |...
Chapter 8 1. Which of control signal lines can be used in the off-chip memory expansion...
Chapter 8 1. Which of control signal lines can be used in the off-chip memory expansion of MCS-51 single chip microcomputer ? Please explain the functions of each control signal line. 10. In single chip microcomputer, we use one chip EPROM2764 and one SRAM6264 to expand memory storage. Assume the initial address of ROM is 000H, and the initial address of RAM is 2000H. Please draw the system circuit scheme, then show the address range clearly.
Chapter 8 1. Which of control signal lines can be used in the off-chip memory expansion...
Chapter 8 1. Which of control signal lines can be used in the off-chip memory expansion of MCS-51 single chip microcomputer ? Please explain the functions of each control signal line. 10. In single chip microcomputer, we use one chip EPROM2764 and one SRAM6264 to expand memory storage. Assume the initial address of ROM is 000H, and the initial address of RAM is 2000H. Please draw the system circuit scheme, then show the address range clearly.
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT