Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <semaphore.h>
- #include <time.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include <pthread.h>
- #include <string.h>
- #include <errno.h>
- #include <getopt.h>
- #include <sys/queue.h>
- #define EATING 0
- #define TALKING 1
- #define WAITING 2
- #define DOT 0
- #define NOTDOT 1
- static char *progname = "IETF Simulation";
- typedef struct attendee {
- int id;
- pthread_t t_id;
- int state;
- int dot;
- } attendee;
- attendee* init_attendee(attendee *myAttendee, int id, int dot);
- void init_attendees(int n);
- void init_tables(int n);
- void *run_att(void *arg);
- void *run_att_dot(void *arg);
- void join_threads(int n);
- void make_threads(int n);
- void cleanup(int att_n, int t_n);
- int getRandom(int max);
- pthread_mutex_t *tables;
- pthread_mutex_t *threads;
- attendee **attendees;
- int id = 0;
- int table_n = 5;
- int attendees_n = 100;
- int attendees_dot = 5;
- int wait_time = 5;
- int conversation = 4;
- int cookie_pickup = 1;
- int max_attendees_hall = 4;
- int main(int argc, char **argv)
- {
- int option = 0;
- srand(time(NULL));
- while ((option = getopt(argc, argv,"t:n:d:w:s:c:m:h")) != -1) {
- switch (option) {
- case 't' : table_n = atoi(optarg);
- break;
- case 'n' : attendees_n = atoi(optarg);
- break;
- case 'd' : attendees_dot = atoi(optarg);
- break;
- case 'w' : wait_time = atoi(optarg);
- break;
- case 's' : conversation = atoi(optarg);
- break;
- case 'c' : cookie_pickup = atoi(optarg);
- break;
- case 'm' : max_attendees_hall = atoi(optarg);
- break;
- }
- }
- init_tables(table_n);
- init_attendees(attendees_n);
- make_threads(attendees_n);
- cleanup(attendees_n, table_n);
- return 0;
- }
- /**
- * Creation of threads for each attendee
- * @param n number of attendees
- */
- void make_threads(int n)
- {
- int i;
- int err;
- for (i = 0; i < n; i++) {
- if (attendees[i]->dot == NOTDOT)
- err = pthread_create(&attendees[i]->t_id, NULL, run_att,
- (void*)attendees[i]);
- else
- err = pthread_create(&attendees[i]->t_id, NULL, run_att_dot,
- (void*)attendees[i]);
- if (err) {
- fprintf(stderr, "[%s]: [%s]: [%s]: cannot create thread : %d! %d\n",
- progname, __func__, strerror(errno), i, err);
- exit(EXIT_FAILURE);
- }
- }
- }
- /**
- * Initialization for attendees array
- * @param n number of attendees
- */
- void init_attendees(int n)
- {
- int i;
- attendees = (attendee**)calloc(n, sizeof(attendee*));
- if (!attendees) {
- fprintf(stderr, "[%s]: [%s]: [%s]: cannot init attendees array!\n",
- progname, __func__, strerror(errno));
- exit(EXIT_FAILURE);
- }
- for(i = 0; i < n; i++)
- if (i < attendees_n - attendees_dot)
- attendees[i] = init_attendee(attendees[i], i, NOTDOT);
- else
- attendees[i] = init_attendee(attendees[i], i, DOT);
- }
- /**
- * Initialization for one attendee
- * @param myAttendee instance of attendee
- * @param id number of the attendee
- * @param dot 0 if it has a dot, 1 otherwise
- * @return Initialized attendee
- */
- attendee* init_attendee(attendee *myAttendee, int id, int dot) {
- myAttendee = (attendee*)calloc(1, sizeof(attendee));
- if (!myAttendee) {
- fprintf(stderr, "[%s]: [%s]: [%s]: cannot init attendee %d!\n",
- progname, __func__, strerror(errno), id);
- exit(EXIT_FAILURE);
- }
- myAttendee->id = id;
- myAttendee->state = WAITING;
- myAttendee->dot = dot;
- return myAttendee;
- }
- /**
- * Initialization for table mutexes
- * @param n number of tables
- */
- void init_tables(int n)
- {
- int i;
- int err;
- tables = (pthread_mutex_t*)calloc(n, sizeof(pthread_mutex_t));
- threads = (pthread_mutex_t*)calloc(attendees_n, sizeof(pthread_mutex_t));
- if (!tables) {
- fprintf(stderr, "[%s]: [%s]: [%s]: cannot init tables!\n",
- progname, __func__, strerror(errno));
- exit(EXIT_FAILURE);
- }
- if (!threads) {
- fprintf(stderr, "[%s]: [%s]: [%s]: cannot init mtx for threads!\n",
- progname, __func__, strerror(errno));
- exit(EXIT_FAILURE);
- }
- for(i = 0; i < n; i++) {
- err = pthread_mutex_init(&tables[i], NULL);
- if (err) {
- fprintf(stderr, "[%s]: [%s]: [%s]: cannot init mutex : %d! %d\n",
- progname, __func__, strerror(errno), i, err);
- exit(EXIT_FAILURE);
- }
- }
- for(i = 0; i < attendees_n; i++) {
- err = pthread_mutex_init(&threads[i], NULL);
- if (err) {
- fprintf(stderr, "[%s]: [%s]: [%s]: cannot init mutex for thread:"\
- " %d! %d\n",progname, __func__, strerror(errno), i, err);
- exit(EXIT_FAILURE);
- }
- }
- }
- /**
- * Main for attendee
- * @param arg instance of attendee
- * @return NULL
- */
- void *run_att(void *arg)
- {
- int err;
- int table_number;
- int cookie;
- struct timespec timeout;
- struct timespec now;
- attendee *iAm = (attendee*)arg;
- pthread_mutex_lock(&threads[iAm->id]);
- cookie = 0;
- table_number = getRandom(table_n);
- while (cookie == 0) {
- clock_gettime(CLOCK_REALTIME, &now);
- timeout.tv_sec = now.tv_sec + wait_time;
- timeout.tv_nsec = now.tv_nsec;
- printf("Att %d wants to eat at table %d!\n" ,iAm->id, table_number);
- err = pthread_mutex_timedlock(&tables[table_number], &timeout);
- if (err == 0) {
- printf("Att %d started eating the cookie at table %d!\n",
- iAm->id, table_number);
- iAm->state = EATING;
- sleep(cookie_pickup);
- printf("Att %d finished eating the cookie!\n", iAm->id);
- cookie = 1;
- err = pthread_mutex_unlock(&tables[table_number]);
- }
- else
- if (err == 110) {
- table_number = getRandom(table_n);
- }
- }
- pthread_mutex_unlock(&threads[iAm->id]);
- return NULL;
- }
- void *run_att_dot(void *arg)
- {
- printf("I have dot!\n");
- return NULL;
- }
- /**
- * Cleanup for the threads
- * @param n number of threads
- */
- void join_threads(int n)
- {
- int i;
- int err;
- for (i = 0; i < n; i++) {
- err = pthread_join(attendees[i]->t_id, NULL);
- if (err) {
- fprintf(stderr, "[%s]: [%s]: [%s]: cannot join thread : %d! %d\n",
- progname, __func__, strerror(errno), i, err);
- exit(EXIT_FAILURE);
- }
- }
- }
- /**
- * Destroys the mutexes for the tables
- * @param n number of tables
- */
- void destroy_mutexes(int n)
- {
- int i;
- int err;
- for(i = 0; i < n; i++) {
- err = pthread_mutex_destroy(&tables[i]);
- if (err) {
- fprintf(stderr, "[%s]: [%s]: [%s]: cannot destroy mutex : %d! %d\n",
- progname, __func__, strerror(errno), i, err);
- exit(EXIT_FAILURE);
- }
- }
- free(tables);
- for(i = 0; i < attendees_n; i++) {
- err = pthread_mutex_destroy(&threads[i]);
- if (err) {
- fprintf(stderr, "[%s]: [%s]: [%s]: cannot destroy mutex : %d! %d\n",
- progname, __func__, strerror(errno), i, err);
- exit(EXIT_FAILURE);
- }
- }
- free(threads);
- }
- /**
- * Deinit all attendees
- * @param n number of attendees
- */
- void destroy_attendees(int n)
- {
- int i;
- for(i = 0; i < n; i++)
- free(attendees[i]);
- free(attendees);
- }
- /**
- * Cleanup wrapper
- * @param att_n number of attendees
- * @param t_n number of tables
- */
- void cleanup(int att_n, int t_n)
- {
- join_threads(att_n);
- destroy_mutexes(t_n);
- destroy_attendees(att_n);
- }
- /**
- * Wrapper to a rand function
- * @param max limit the range
- * @return the rand value
- */
- int getRandom(int max) {
- return rand() % max;
- }
Advertisement
Add Comment
Please, Sign In to add comment