fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pthread.h>
  4. #include <semaphore.h>
  5. #include <unistd.h>
  6. #include <stdint.h>
  7. #include <string.h>
  8. #include <time.h>
  9.  
  10. #define MAX_THREADS 10
  11. #define OPS 5
  12. #define TEST_CASES 3
  13.  
  14. int BUFFER = 0;
  15.  
  16. // Semaphores
  17. sem_t buffer_sem;
  18. sem_t read_count_sem;
  19. sem_t password_sem;
  20.  
  21. int read_count = 0;
  22.  
  23. // Password table
  24. unsigned long password_table[MAX_THREADS];
  25. int table_size = 0;
  26.  
  27. typedef struct {
  28. int thread_no;
  29. unsigned long hash_val;
  30. char validity[8];
  31. char role[8];
  32. int value;
  33. } log_entry_t;
  34.  
  35. log_entry_t logs[TEST_CASES][40];
  36. int log_pos[TEST_CASES] = {0};
  37.  
  38. typedef struct {
  39. int thread_no;
  40. int is_reader;
  41. int is_real;
  42. int test_case;
  43. } ThreadInfo;
  44.  
  45. unsigned long hash_pthread_t(pthread_t thread_id) {
  46. return (unsigned long)(uintptr_t)thread_id;
  47. }
  48.  
  49. void register_thread(pthread_t tid) {
  50. sem_wait(&password_sem);
  51. password_table[table_size++] = hash_pthread_t(tid);
  52. sem_post(&password_sem);
  53. }
  54.  
  55. int is_valid_thread(pthread_t tid) {
  56. unsigned long h = hash_pthread_t(tid);
  57. sem_wait(&password_sem);
  58. for (int i = 0; i < table_size; i++) {
  59. if (password_table[i] == h) {
  60. sem_post(&password_sem);
  61. return 1;
  62. }
  63. }
  64. sem_post(&password_sem);
  65. return 0;
  66. }
  67.  
  68. void log_action(int case_id, int thread_no, pthread_t tid, int is_real, int is_reader, int value) {
  69. log_entry_t *entry = &logs[case_id][log_pos[case_id]++];
  70. entry->thread_no = thread_no;
  71. entry->hash_val = hash_pthread_t(tid);
  72. strcpy(entry->validity, is_real ? "real" : "dummy");
  73. strcpy(entry->role, is_reader ? "reader" : "writer");
  74. entry->value = value;
  75. }
  76.  
  77. void *reader_func(void *arg) {
  78. ThreadInfo *info = (ThreadInfo *)arg;
  79. srand(time(NULL) ^ (uintptr_t)pthread_self());
  80. if (info->is_real) register_thread(pthread_self());
  81.  
  82. for (int i = 0; i < OPS; i++) {
  83. sleep(1);
  84. if (!is_valid_thread(pthread_self())) {
  85. log_action(info->test_case, info->thread_no, pthread_self(), info->is_real, 1, -1);
  86. continue;
  87. }
  88.  
  89. sem_wait(&read_count_sem);
  90. read_count++;
  91. if (read_count == 1) sem_wait(&buffer_sem);
  92. sem_post(&read_count_sem);
  93.  
  94. log_action(info->test_case, info->thread_no, pthread_self(), info->is_real, 1, BUFFER);
  95.  
  96. sem_wait(&read_count_sem);
  97. read_count--;
  98. if (read_count == 0) sem_post(&buffer_sem);
  99. sem_post(&read_count_sem);
  100. }
  101.  
  102. free(info);
  103. return NULL;
  104. }
  105.  
  106. void *writer_func(void *arg) {
  107. ThreadInfo *info = (ThreadInfo *)arg;
  108. srand(time(NULL) ^ (uintptr_t)pthread_self());
  109. if (info->is_real) register_thread(pthread_self());
  110.  
  111. for (int i = 0; i < OPS; i++) {
  112. sleep(1);
  113. if (!is_valid_thread(pthread_self())) {
  114. log_action(info->test_case, info->thread_no, pthread_self(), info->is_real, 0, -1);
  115. continue;
  116. }
  117.  
  118. sem_wait(&buffer_sem);
  119. int val = rand() % 10000;
  120. BUFFER = val;
  121. log_action(info->test_case, info->thread_no, pthread_self(), info->is_real, 0, val);
  122. sem_post(&buffer_sem);
  123. }
  124.  
  125. free(info);
  126. return NULL;
  127. }
  128.  
  129. void print_log(int case_id) {
  130. printf("===== Test Case %d =====\n", case_id + 1);
  131. printf("Thread_No | Hash_Value | Validity | Role | Value\n");
  132. printf("--------------------------------------------------------\n");
  133. for (int i = 0; i < log_pos[case_id]; i++) {
  134. printf("%9d | %016lx | %7s | %6s | %5d\n",
  135. logs[case_id][i].thread_no,
  136. logs[case_id][i].hash_val,
  137. logs[case_id][i].validity,
  138. logs[case_id][i].role,
  139. logs[case_id][i].value);
  140. }
  141. printf("\n");
  142. }
  143.  
  144. int main() {
  145. srand(time(NULL));
  146.  
  147. sem_init(&buffer_sem, 0, 1);
  148. sem_init(&read_count_sem, 0, 1);
  149. sem_init(&password_sem, 0, 1);
  150.  
  151. int test_cases[3][2] = {{2, 2}, {3, 1}, {1, 4}};
  152. pthread_t threads[40];
  153. int tcount = 0;
  154.  
  155. for (int t = 0; t < TEST_CASES; t++) {
  156. int readers = test_cases[t][0];
  157. int writers = test_cases[t][1];
  158.  
  159. for (int i = 0; i < readers; i++) {
  160. ThreadInfo *info = malloc(sizeof(ThreadInfo));
  161. *info = (ThreadInfo){.thread_no = tcount + 1, .is_reader = 1, .is_real = 1, .test_case = t};
  162. pthread_create(&threads[tcount], NULL, reader_func, info);
  163. tcount++;
  164. }
  165. for (int i = 0; i < writers; i++) {
  166. ThreadInfo *info = malloc(sizeof(ThreadInfo));
  167. *info = (ThreadInfo){.thread_no = tcount + 1, .is_reader = 0, .is_real = 1, .test_case = t};
  168. pthread_create(&threads[tcount], NULL, writer_func, info);
  169. tcount++;
  170. }
  171. for (int i = 0; i < readers; i++) {
  172. ThreadInfo *info = malloc(sizeof(ThreadInfo));
  173. *info = (ThreadInfo){.thread_no = tcount + 1, .is_reader = 1, .is_real = 0, .test_case = t};
  174. pthread_create(&threads[tcount], NULL, reader_func, info);
  175. tcount++;
  176. }
  177. for (int i = 0; i < writers; i++) {
  178. ThreadInfo *info = malloc(sizeof(ThreadInfo));
  179. *info = (ThreadInfo){.thread_no = tcount + 1, .is_reader = 0, .is_real = 0, .test_case = t};
  180. pthread_create(&threads[tcount], NULL, writer_func, info);
  181. tcount++;
  182. }
  183. }
  184.  
  185. for (int i = 0; i < tcount; i++) {
  186. pthread_join(threads[i], NULL);
  187. }
  188.  
  189. for (int t = 0; t < TEST_CASES; t++) {
  190. print_log(t);
  191. }
  192.  
  193. return 0;
  194. }
Success #stdin #stdout 0.01s 5320KB
stdin
Standard input is empty
stdout
===== Test Case 1 =====
Thread_No | Hash_Value       | Validity | Role   | Value
--------------------------------------------------------
        7 | 00001506a24d6700 |   dummy  | writer |    -1
        8 | 00001506a22d5700 |   dummy  | writer |    -1
        6 | 00001506a26d7700 |   dummy  | reader |    -1
        5 | 00001506a28d8700 |   dummy  | reader |    -1
        4 | 00001506a2ad9700 |    real  | writer |  4570
        3 | 00001506a2cda700 |    real  | writer |  4722
        2 | 00001506a2edb700 |    real  | reader |  4722
        1 | 00001506a30dc700 |    real  | reader |  4722
        7 | 00001506a24d6700 |   dummy  | writer |    -1
        8 | 00001506a22d5700 |   dummy  | writer |    -1
        6 | 00001506a26d7700 |   dummy  | reader |    -1
        5 | 00001506a28d8700 |   dummy  | reader |    -1
        4 | 00001506a2ad9700 |    real  | writer |  9229
        3 | 00001506a2cda700 |    real  | writer |  9264
        2 | 00001506a2edb700 |    real  | reader |  9264
        1 | 00001506a30dc700 |    real  | reader |  9264
        7 | 00001506a24d6700 |   dummy  | writer |    -1
        8 | 00001506a22d5700 |   dummy  | writer |    -1
        6 | 00001506a26d7700 |   dummy  | reader |    -1
        5 | 00001506a28d8700 |   dummy  | reader |    -1
        4 | 00001506a2ad9700 |    real  | writer |  2213
        3 | 00001506a2cda700 |    real  | writer |  7243
        2 | 00001506a2edb700 |    real  | reader |  7243
        1 | 00001506a30dc700 |    real  | reader |  7243
        7 | 00001506a24d6700 |   dummy  | writer |    -1
        8 | 00001506a22d5700 |   dummy  | writer |    -1
        6 | 00001506a26d7700 |   dummy  | reader |    -1
        5 | 00001506a28d8700 |   dummy  | reader |    -1
        4 | 00001506a2ad9700 |    real  | writer |  7487
        3 | 00001506a2cda700 |    real  | writer |  3365
        2 | 00001506a2edb700 |    real  | reader |  3365
        1 | 00001506a30dc700 |    real  | reader |  3365
        7 | 00001506a24d6700 |   dummy  | writer |    -1
        8 | 00001506a22d5700 |   dummy  | writer |    -1
        6 | 00001506a26d7700 |   dummy  | reader |    -1
        5 | 00001506a28d8700 |   dummy  | reader |    -1
        4 | 00001506a2ad9700 |    real  | writer |  1783
        3 | 00001506a2cda700 |    real  | writer |   850
        2 | 00001506a2edb700 |    real  | reader |   850
        1 | 00001506a30dc700 |    real  | reader |   850

===== Test Case 2 =====
Thread_No | Hash_Value       | Validity | Role   | Value
--------------------------------------------------------
        9 | 00001506a20d4700 |    real  | reader |     0
       10 | 00001506a1ed3700 |    real  | reader |     0
       11 | 00001506a1cd2700 |    real  | reader |     0
       12 | 00001506a1ad1700 |    real  | writer |  3647
       13 | 00001506a18d0700 |   dummy  | reader |    -1
       14 | 00001506a16cf700 |   dummy  | reader |    -1
       15 | 00001506a14ce700 |   dummy  | reader |    -1
        9 | 00001506a20d4700 |    real  | reader |  4722
       10 | 00001506a1ed3700 |    real  | reader |  4722
       11 | 00001506a1cd2700 |    real  | reader |  4722
       12 | 00001506a1ad1700 |    real  | writer |  8422
       13 | 00001506a18d0700 |   dummy  | reader |    -1
       14 | 00001506a16cf700 |   dummy  | reader |    -1
       15 | 00001506a14ce700 |   dummy  | reader |    -1
        9 | 00001506a20d4700 |    real  | reader |  9264
       10 | 00001506a1ed3700 |    real  | reader |  9264
       11 | 00001506a1cd2700 |    real  | reader |  9264
       12 | 00001506a1ad1700 |    real  | writer |  2410
       13 | 00001506a18d0700 |   dummy  | reader |    -1
       14 | 00001506a16cf700 |   dummy  | reader |    -1
       15 | 00001506a14ce700 |   dummy  | reader |    -1
        9 | 00001506a20d4700 |    real  | reader |  7243
       10 | 00001506a1ed3700 |    real  | reader |  7243
       11 | 00001506a1cd2700 |    real  | reader |  7243
       12 | 00001506a1ad1700 |    real  | writer |  2904
       13 | 00001506a18d0700 |   dummy  | reader |    -1
       14 | 00001506a16cf700 |   dummy  | reader |    -1
       15 | 00001506a14ce700 |   dummy  | reader |    -1
        9 | 00001506a20d4700 |    real  | reader |  3365
       10 | 00001506a1ed3700 |    real  | reader |  3365
       11 | 00001506a1cd2700 |    real  | reader |  3365
       12 | 00001506a1ad1700 |    real  | writer |  5984
       13 | 00001506a18d0700 |   dummy  | reader |    -1
       14 | 00001506a16cf700 |   dummy  | reader |    -1
       15 | 00001506a14ce700 |   dummy  | reader |    -1

===== Test Case 3 =====
Thread_No | Hash_Value       | Validity | Role   | Value
--------------------------------------------------------