Без опису
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

main-two-cvs-while-extra-unlock.c 2.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #include <ctype.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <assert.h>
  6. #include <pthread.h>
  7. #include <sys/time.h>
  8. #include <string.h>
  9. #include "mythreads.h"
  10. #include "pc-header.h"
  11. pthread_cond_t empty = PTHREAD_COND_INITIALIZER;
  12. pthread_cond_t fill = PTHREAD_COND_INITIALIZER;
  13. pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
  14. #include "main-header.h"
  15. void do_fill(int value) {
  16. // ensure empty before usage
  17. ensure(buffer[fill_ptr] == EMPTY, "error: tried to fill a non-empty buffer");
  18. buffer[fill_ptr] = value;
  19. fill_ptr = (fill_ptr + 1) % max;
  20. num_full++;
  21. }
  22. int do_get() {
  23. int tmp = buffer[use_ptr];
  24. ensure(tmp != EMPTY, "error: tried to get an empty buffer");
  25. buffer[use_ptr] = EMPTY;
  26. use_ptr = (use_ptr + 1) % max;
  27. num_full--;
  28. return tmp;
  29. }
  30. void *producer(void *arg) {
  31. long int id = (long int) arg;
  32. // make sure each producer produces unique values
  33. int base = id * loops;
  34. int i;
  35. for (i = 0; i < loops; i++) { p0;
  36. Mutex_lock(&m); p1;
  37. while (num_full == max) { p2;
  38. Cond_wait(&empty, &m); p3;
  39. }
  40. Mutex_unlock(&m);
  41. do_fill(base + i); p4;
  42. Mutex_lock(&m);
  43. Cond_signal(&fill); p5;
  44. Mutex_unlock(&m); p6;
  45. }
  46. return NULL;
  47. }
  48. void *consumer(void *arg) {
  49. long int id = (long int) arg;
  50. int tmp = 0;
  51. int consumed_count = 0;
  52. while (tmp != END_OF_STREAM) { c0;
  53. Mutex_lock(&m); c1;
  54. while (num_full == 0) { c2;
  55. Cond_wait(&fill, &m); c3;
  56. }
  57. Mutex_unlock(&m);
  58. tmp = do_get(); c4;
  59. Mutex_lock(&m);
  60. Cond_signal(&empty); c5;
  61. Mutex_unlock(&m); c6;
  62. consumed_count++;
  63. }
  64. // return consumer_count-1 because END_OF_STREAM does not count
  65. return (void *) (long long) (consumed_count - 1);
  66. }
  67. // must set these appropriately to use "main-common.c"
  68. pthread_cond_t *fill_cv = &fill;
  69. pthread_cond_t *empty_cv = &empty;
  70. // all codes use this common base to start producers/consumers
  71. // and all the other related stuff
  72. #include "main-common.c"