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

===== Test Case 2 =====
Thread_No | Hash_Value       | Validity | Role   | Value
--------------------------------------------------------
        9 | 000015027cb7d700 |    real  | reader |     0
       10 | 000015027c97c700 |    real  | reader |     0
       11 | 000015027c77b700 |    real  | reader |     0
       12 | 000015027c57a700 |    real  | writer |  6174
       13 | 000015027c379700 |   dummy  | reader |    -1
       14 | 000015027c178700 |   dummy  | reader |    -1
       15 | 000015027bf77700 |   dummy  | reader |    -1
        9 | 000015027cb7d700 |    real  | reader |  6715
       10 | 000015027c97c700 |    real  | reader |  6715
       11 | 000015027c77b700 |    real  | reader |  6715
       12 | 000015027c57a700 |    real  | writer |  6678
       13 | 000015027c379700 |   dummy  | reader |    -1
       14 | 000015027c178700 |   dummy  | reader |    -1
       15 | 000015027bf77700 |   dummy  | reader |    -1
        9 | 000015027cb7d700 |    real  | reader |  4927
       10 | 000015027c97c700 |    real  | reader |  4927
       11 | 000015027c77b700 |    real  | reader |  4927
       12 | 000015027c57a700 |    real  | writer |  3849
       13 | 000015027c379700 |   dummy  | reader |    -1
       14 | 000015027c178700 |   dummy  | reader |    -1
       15 | 000015027bf77700 |   dummy  | reader |    -1
        9 | 000015027cb7d700 |    real  | reader |  4471
       10 | 000015027c97c700 |    real  | reader |  4471
       11 | 000015027c77b700 |    real  | reader |  4471
       12 | 000015027c57a700 |    real  | writer |  4731
       13 | 000015027c379700 |   dummy  | reader |    -1
       14 | 000015027c178700 |   dummy  | reader |    -1
       15 | 000015027bf77700 |   dummy  | reader |    -1
        9 | 000015027cb7d700 |    real  | reader |  3665
       10 | 000015027c97c700 |    real  | reader |  3665
       11 | 000015027c77b700 |    real  | reader |  3665
       12 | 000015027c57a700 |    real  | writer |  9176
       13 | 000015027c379700 |   dummy  | reader |    -1
       14 | 000015027c178700 |   dummy  | reader |    -1
       15 | 000015027bf77700 |   dummy  | reader |    -1

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