ungureanuvladvictor

Untitled

Mar 5th, 2014
227
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.23 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <semaphore.h>
  4. #include <time.h>
  5. #include <sys/stat.h>
  6. #include <unistd.h>
  7. #include <pthread.h>
  8. #include <string.h>
  9. #include <errno.h>
  10. #include <getopt.h>
  11. #include <sys/queue.h>
  12.  
  13. #define EATING 0
  14. #define TALKING 1
  15. #define WAITING 2
  16. #define DOT 0
  17. #define NOTDOT 1
  18.  
  19. static char *progname = "IETF Simulation";
  20.  
  21. typedef struct attendee {
  22. int id;
  23. pthread_t t_id;
  24. int state;
  25. int dot;
  26. } attendee;
  27.  
  28. attendee* init_attendee(attendee *myAttendee, int id, int dot);
  29. void init_attendees(int n);
  30. void init_tables(int n);
  31. void *run_att(void *arg);
  32. void *run_att_dot(void *arg);
  33. void join_threads(int n);
  34. void make_threads(int n);
  35. void cleanup(int att_n, int t_n);
  36. int getRandom(int max);
  37.  
  38. pthread_mutex_t *tables;
  39. pthread_mutex_t *threads;
  40. attendee **attendees;
  41.  
  42. int id = 0;
  43. int table_n = 5;
  44. int attendees_n = 100;
  45. int attendees_dot = 5;
  46. int wait_time = 5;
  47. int conversation = 4;
  48. int cookie_pickup = 1;
  49. int max_attendees_hall = 4;
  50.  
  51. int main(int argc, char **argv)
  52. {
  53. int option = 0;
  54.  
  55. srand(time(NULL));
  56. while ((option = getopt(argc, argv,"t:n:d:w:s:c:m:h")) != -1) {
  57. switch (option) {
  58. case 't' : table_n = atoi(optarg);
  59. break;
  60. case 'n' : attendees_n = atoi(optarg);
  61. break;
  62. case 'd' : attendees_dot = atoi(optarg);
  63. break;
  64. case 'w' : wait_time = atoi(optarg);
  65. break;
  66. case 's' : conversation = atoi(optarg);
  67. break;
  68. case 'c' : cookie_pickup = atoi(optarg);
  69. break;
  70. case 'm' : max_attendees_hall = atoi(optarg);
  71. break;
  72. }
  73. }
  74.  
  75. init_tables(table_n);
  76. init_attendees(attendees_n);
  77. make_threads(attendees_n);
  78. cleanup(attendees_n, table_n);
  79.  
  80. return 0;
  81. }
  82.  
  83. /**
  84. * Creation of threads for each attendee
  85. * @param n number of attendees
  86. */
  87. void make_threads(int n)
  88. {
  89. int i;
  90. int err;
  91.  
  92. for (i = 0; i < n; i++) {
  93. if (attendees[i]->dot == NOTDOT)
  94. err = pthread_create(&attendees[i]->t_id, NULL, run_att,
  95. (void*)attendees[i]);
  96. else
  97. err = pthread_create(&attendees[i]->t_id, NULL, run_att_dot,
  98. (void*)attendees[i]);
  99. if (err) {
  100. fprintf(stderr, "[%s]: [%s]: [%s]: cannot create thread : %d! %d\n",
  101. progname, __func__, strerror(errno), i, err);
  102. exit(EXIT_FAILURE);
  103. }
  104. }
  105. }
  106.  
  107. /**
  108. * Initialization for attendees array
  109. * @param n number of attendees
  110. */
  111. void init_attendees(int n)
  112. {
  113. int i;
  114. attendees = (attendee**)calloc(n, sizeof(attendee*));
  115. if (!attendees) {
  116. fprintf(stderr, "[%s]: [%s]: [%s]: cannot init attendees array!\n",
  117. progname, __func__, strerror(errno));
  118. exit(EXIT_FAILURE);
  119. }
  120.  
  121. for(i = 0; i < n; i++)
  122. if (i < attendees_n - attendees_dot)
  123. attendees[i] = init_attendee(attendees[i], i, NOTDOT);
  124. else
  125. attendees[i] = init_attendee(attendees[i], i, DOT);
  126. }
  127.  
  128. /**
  129. * Initialization for one attendee
  130. * @param myAttendee instance of attendee
  131. * @param id number of the attendee
  132. * @param dot 0 if it has a dot, 1 otherwise
  133. * @return Initialized attendee
  134. */
  135. attendee* init_attendee(attendee *myAttendee, int id, int dot) {
  136. myAttendee = (attendee*)calloc(1, sizeof(attendee));
  137. if (!myAttendee) {
  138. fprintf(stderr, "[%s]: [%s]: [%s]: cannot init attendee %d!\n",
  139. progname, __func__, strerror(errno), id);
  140. exit(EXIT_FAILURE);
  141. }
  142.  
  143. myAttendee->id = id;
  144. myAttendee->state = WAITING;
  145. myAttendee->dot = dot;
  146.  
  147. return myAttendee;
  148. }
  149.  
  150.  
  151. /**
  152. * Initialization for table mutexes
  153. * @param n number of tables
  154. */
  155. void init_tables(int n)
  156. {
  157. int i;
  158. int err;
  159. tables = (pthread_mutex_t*)calloc(n, sizeof(pthread_mutex_t));
  160. threads = (pthread_mutex_t*)calloc(attendees_n, sizeof(pthread_mutex_t));
  161.  
  162. if (!tables) {
  163. fprintf(stderr, "[%s]: [%s]: [%s]: cannot init tables!\n",
  164. progname, __func__, strerror(errno));
  165. exit(EXIT_FAILURE);
  166. }
  167.  
  168. if (!threads) {
  169. fprintf(stderr, "[%s]: [%s]: [%s]: cannot init mtx for threads!\n",
  170. progname, __func__, strerror(errno));
  171. exit(EXIT_FAILURE);
  172. }
  173.  
  174. for(i = 0; i < n; i++) {
  175. err = pthread_mutex_init(&tables[i], NULL);
  176. if (err) {
  177. fprintf(stderr, "[%s]: [%s]: [%s]: cannot init mutex : %d! %d\n",
  178. progname, __func__, strerror(errno), i, err);
  179. exit(EXIT_FAILURE);
  180. }
  181. }
  182.  
  183. for(i = 0; i < attendees_n; i++) {
  184. err = pthread_mutex_init(&threads[i], NULL);
  185. if (err) {
  186. fprintf(stderr, "[%s]: [%s]: [%s]: cannot init mutex for thread:"\
  187. " %d! %d\n",progname, __func__, strerror(errno), i, err);
  188. exit(EXIT_FAILURE);
  189. }
  190. }
  191. }
  192.  
  193. /**
  194. * Main for attendee
  195. * @param arg instance of attendee
  196. * @return NULL
  197. */
  198. void *run_att(void *arg)
  199. {
  200. int err;
  201. int table_number;
  202. int cookie;
  203. struct timespec timeout;
  204. struct timespec now;
  205. attendee *iAm = (attendee*)arg;
  206.  
  207. pthread_mutex_lock(&threads[iAm->id]);
  208.  
  209. cookie = 0;
  210. table_number = getRandom(table_n);
  211. while (cookie == 0) {
  212. clock_gettime(CLOCK_REALTIME, &now);
  213. timeout.tv_sec = now.tv_sec + wait_time;
  214. timeout.tv_nsec = now.tv_nsec;
  215.  
  216. printf("Att %d wants to eat at table %d!\n" ,iAm->id, table_number);
  217.  
  218. err = pthread_mutex_timedlock(&tables[table_number], &timeout);
  219. if (err == 0) {
  220. printf("Att %d started eating the cookie at table %d!\n",
  221. iAm->id, table_number);
  222. iAm->state = EATING;
  223. sleep(cookie_pickup);
  224. printf("Att %d finished eating the cookie!\n", iAm->id);
  225. cookie = 1;
  226. err = pthread_mutex_unlock(&tables[table_number]);
  227. }
  228. else
  229. if (err == 110) {
  230. table_number = getRandom(table_n);
  231. }
  232. }
  233.  
  234. pthread_mutex_unlock(&threads[iAm->id]);
  235. return NULL;
  236. }
  237.  
  238. void *run_att_dot(void *arg)
  239. {
  240. printf("I have dot!\n");
  241. return NULL;
  242. }
  243.  
  244. /**
  245. * Cleanup for the threads
  246. * @param n number of threads
  247. */
  248. void join_threads(int n)
  249. {
  250. int i;
  251. int err;
  252.  
  253. for (i = 0; i < n; i++) {
  254. err = pthread_join(attendees[i]->t_id, NULL);
  255. if (err) {
  256. fprintf(stderr, "[%s]: [%s]: [%s]: cannot join thread : %d! %d\n",
  257. progname, __func__, strerror(errno), i, err);
  258. exit(EXIT_FAILURE);
  259. }
  260. }
  261. }
  262.  
  263. /**
  264. * Destroys the mutexes for the tables
  265. * @param n number of tables
  266. */
  267. void destroy_mutexes(int n)
  268. {
  269. int i;
  270. int err;
  271. for(i = 0; i < n; i++) {
  272. err = pthread_mutex_destroy(&tables[i]);
  273. if (err) {
  274. fprintf(stderr, "[%s]: [%s]: [%s]: cannot destroy mutex : %d! %d\n",
  275. progname, __func__, strerror(errno), i, err);
  276. exit(EXIT_FAILURE);
  277. }
  278. }
  279.  
  280. free(tables);
  281.  
  282. for(i = 0; i < attendees_n; i++) {
  283. err = pthread_mutex_destroy(&threads[i]);
  284. if (err) {
  285. fprintf(stderr, "[%s]: [%s]: [%s]: cannot destroy mutex : %d! %d\n",
  286. progname, __func__, strerror(errno), i, err);
  287. exit(EXIT_FAILURE);
  288. }
  289. }
  290.  
  291. free(threads);
  292. }
  293.  
  294. /**
  295. * Deinit all attendees
  296. * @param n number of attendees
  297. */
  298. void destroy_attendees(int n)
  299. {
  300. int i;
  301. for(i = 0; i < n; i++)
  302. free(attendees[i]);
  303. free(attendees);
  304.  
  305. }
  306.  
  307. /**
  308. * Cleanup wrapper
  309. * @param att_n number of attendees
  310. * @param t_n number of tables
  311. */
  312. void cleanup(int att_n, int t_n)
  313. {
  314. join_threads(att_n);
  315. destroy_mutexes(t_n);
  316. destroy_attendees(att_n);
  317. }
  318.  
  319. /**
  320. * Wrapper to a rand function
  321. * @param max limit the range
  322. * @return the rand value
  323. */
  324. int getRandom(int max) {
  325. return rand() % max;
  326. }
Advertisement
Add Comment
Please, Sign In to add comment