Advertisement
Guest User

Untitled

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