Advertisement
Guest User

Untitled

a guest
Oct 19th, 2019
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.70 KB | None | 0 0
  1. #include "enzyme.h"
  2.  
  3.  
  4.  
  5. int please_quit;
  6. int use_yield;
  7. int workperformed;
  8.  
  9. // The code each enzyme executes.
  10. void *run_enzyme(void *data) {
  11. /* This function should :
  12. 1. cast the void* pointer to thread_info_t*
  13. 2. initialize the swapcount to zero
  14. 3. Set the cancel type to PTHREAD_CANCEL_ASYNCHRONOUS
  15. 4. If the first letter of the string is a C then call pthread_cancel on this thread.
  16. 5. Create a while loop that only exits when please_quit is nonzero
  17. 6. Within this loop: if the first character of the string has an ascii value greater than the second (s[0] >s[1]) then -
  18. Set workperformed=1, increment swapcount for this thread, then swap the two characters around
  19. If "use_yield" is nonzero then call pthread_yield at the end of the loop.
  20. 7. Return a pointer to the updated structure.
  21. */
  22.  
  23. thread_info_t* newData = (thread_info_t *)malloc(sizeof(thread_info_t));
  24. newData = (thread_info_t *)data;
  25. newData->swapcount = 0;
  26. pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
  27. char swapChar;
  28. pthread_t currentThread = pthread_self();
  29.  
  30. if((newData->string[0] == 'C') || (newData->string[0] == 'c')){
  31. pthread_cancel(currentThread);
  32. }
  33.  
  34. while(please_quit == 0){
  35. if(newData->string[0] > newData->string[1]){
  36. workperformed = 1;
  37. newData->swapcount++;
  38. swapChar = newData->string[0];
  39. newData->string[0] = newData->string[1];
  40. newData->string[1] = swapChar;
  41. }
  42. if(!(use_yield == 0)){
  43. sched_yield();
  44. }
  45. }
  46.  
  47. while(0) {
  48. sched_yield();
  49. };
  50.  
  51. return newData;
  52. }
  53.  
  54.  
  55. // Make threads to sort string.
  56. // Returns the number of threads created.
  57. // There is a memory bug in this function.
  58. int make_enzyme_threads(pthread_t * enzymes, char *string, void *(*fp)(void *)) {
  59. int i,rv,len;
  60. thread_info_t *info;
  61. len = strlen(string);
  62. info = (thread_info_t *)malloc(sizeof(thread_info_t));
  63.  
  64. // reallocated more space for the string since the struct only contains a pointer
  65. info->string = realloc(info->string, sizeof(char)*len);
  66.  
  67. for(i=0;i<len-1;i++) {
  68. info->string = string+i;
  69. rv = pthread_create(enzymes+i,NULL,fp,info);
  70. if (rv) {
  71. fprintf(stderr,"Could not create thread %d : %s\n", i, strerror(rv));
  72. exit(1);
  73. }
  74. }
  75. return len-1;
  76. }
  77.  
  78.  
  79.  
  80.  
  81. // Join all threads at the end.
  82. // Returns the total number of swaps.
  83. int join_on_enzymes(pthread_t *threads, int n) {
  84. int i;
  85. int totalswapcount = 0;
  86. //int whatgoeshere=0; // just to make the code compile
  87. // you will need to edit the code below
  88. for(i=0;i<n;i++) {
  89. void *status;
  90. int rv = pthread_join(threads[i],&status);
  91.  
  92. if(rv != 0) { // changed rv != 0
  93. fprintf(stderr,"Can't join thread %d:%s.\n",i,strerror(rv));
  94. continue;
  95. }
  96.  
  97. if ((void*)status == PTHREAD_CANCELED) { // Changed status
  98. continue;
  99. } else if (status == NULL) {
  100. printf("Thread %d did not return anything\n",i);
  101. } else {
  102. printf("Thread %d exited normally: ",i);// Don't change this line
  103. int threadswapcount = *((int*)status);
  104. // Hint - you will need to cast something.
  105. printf("%d swaps.\n",threadswapcount); // Don't change this line
  106. totalswapcount += threadswapcount;// Don't change this line
  107. }
  108. }
  109. return totalswapcount;
  110. }
  111.  
  112. /* 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
  113. so that the string temporarily is in order because the swap is not complete.
  114. */
  115. void wait_till_done(char *string, int n) {
  116. int i;
  117. while(1) {
  118. sched_yield();
  119. workperformed=0;
  120. for(i=0;i<n;i++)
  121. if (string[i] > string[i+1]) {
  122. workperformed=1;
  123. }
  124. if(workperformed==0) break;
  125. }
  126. }
  127.  
  128. void * sleeper_func(void *p) {
  129. sleep( (int) p);
  130. // Actually this may return before p seconds because of signals.
  131. // See man sleep for more information
  132. printf("sleeper func woke up - exiting the program\n");
  133. exit(1);
  134. }
  135.  
  136. int smp2_main(int argc, char **argv) {
  137. pthread_t enzymes[MAX];
  138. int n,totalswap;
  139. char string[MAX];
  140.  
  141. if (argc <= 1) {
  142. fprintf(stderr,"Usage: %s <word>\n",argv[0]);
  143. exit(1);
  144. }
  145. strncpy(string,argv[1],MAX); // Why is this necessary? Why cant we give argv[1] directly to the thread functions?
  146.  
  147. please_quit = 0;
  148. use_yield =1;
  149.  
  150. printf("Creating threads...\n");
  151. n = make_enzyme_threads(enzymes,string,run_enzyme);
  152. printf("Done creating %d threads.\n",n);
  153.  
  154. pthread_t sleeperid;
  155. pthread_create(&sleeperid,NULL,sleeper_func,(void*)5);
  156.  
  157. wait_till_done(string,n);
  158. please_quit = 1;
  159. printf("Joining threads...\n");
  160. totalswap = join_on_enzymes(enzymes, n);
  161. printf("Total: %d swaps\n",totalswap);
  162. printf("Sorted string: %s\n",string);
  163.  
  164. exit(0);
  165. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement