Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #include <pthread.h>
- #include <semaphore.h>
- #include <fcntl.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include <errno.h>
- #include <string.h>
- char *progname = "bathroom";
- pthread_t ppl[20];
- sem_t *semaphore_m, *semaphore_f, *mutex_boy, *mutex_girl;
- sem_t *new_person, *empty;
- int male_counter = 0;
- int female_counter = 0;
- void shuffle(void *obj, int nmemb, size_t size);
- void init_humans(char *humans);
- size_t rrand(int m);
- void mk_threads(char* people, int n);
- void join_threads(int n);
- void *run_m(void *arg);
- void *run_f(void *arg);
- void mk_sem();
- void free_sem();
- void finish();
- void init_humans(char *humans) {
- int i;
- for (i = 0; i < 20; ++i)
- if (i < 9)
- humans[i] = 'm';
- else
- humans[i] = 'f';
- }
- size_t rrand(int m) {
- return (size_t)((double)m * ( rand() / (RAND_MAX+1.0) ));
- }
- #define BYTE(X) ((unsigned char *)(X))
- void shuffle(void *obj, int nmemb, size_t size) {
- void *temp = malloc(size);
- int n = nmemb;
- while ( n > 1 ) {
- size_t k = rrand(n--);
- memcpy(temp, BYTE(obj) + n * size, size);
- memcpy(BYTE(obj) + n * size, BYTE(obj) + k * size, size);
- memcpy(BYTE(obj) + k * size, temp, size);
- }
- free(temp);
- }
- void mk_threads(char* people, int n) {
- int i, err;
- for (i = 0; i < n; i++) {
- if (people[i] == 'm')
- err = pthread_create(&ppl[i], NULL, run_m, NULL);
- else
- err = pthread_create(&ppl[i], NULL, run_f, NULL);
- if (err) {
- fprintf(stderr, "[%s]:[%s]:[%s] - Cannot create thread: %d\n",
- progname, __func__, strerror(errno), i);
- exit(EXIT_FAILURE);
- }
- }
- }
- void join_threads(int n) {
- int i, err;
- for (i = 0; i < n; i++) {
- err = pthread_join(ppl[i], NULL);
- if(err) {
- fprintf(stderr, "[%s]:[%s]:[%s] - Cannot join thread: %d\n",
- progname, __func__, strerror(errno), i);
- exit(EXIT_FAILURE);
- }
- }
- }
- void *run_m(void *arg) {
- sem_wait(new_person);
- sem_wait(mutex_boy);
- male_counter++;
- if (male_counter == 1)
- sem_wait(empty);
- sem_post(mutex_boy);
- sem_wait(semaphore_m);
- sem_post(new_person);
- fprintf(stdout, "Boy in the bathroom\n");
- usleep(123456 + rand() % 123456);
- sem_post(semaphore_m);
- sem_wait(mutex_boy);
- male_counter--;
- if (male_counter == 0)
- sem_post(empty);
- sem_post(mutex_boy);
- return NULL;
- }
- void *run_f(void *arg) {
- sem_wait(new_person);
- sem_wait(mutex_girl);
- female_counter++;
- if (female_counter == 1)
- sem_wait(empty);
- sem_post(mutex_girl);
- sem_wait(semaphore_f);
- sem_post(new_person);
- fprintf(stdout, "Girl in the bathroom!\n");
- usleep(123456 + rand() % 123456);
- sem_post(semaphore_f);
- sem_wait(mutex_girl);
- female_counter--;
- if (female_counter == 0)
- sem_post(empty);
- sem_post(mutex_girl);
- return NULL;
- }
- void mk_sem() {
- if ((semaphore_m = sem_open("/m", O_CREAT,
- 0644, 3)) == SEM_FAILED) {
- fprintf(stderr, "[%s]:[%s] - Cannot create semaphore male!\n",
- progname, strerror(errno), __func__);
- exit(EXIT_FAILURE);
- }
- if ((semaphore_f = sem_open("/f", O_CREAT,
- 0644, 3)) == SEM_FAILED) {
- fprintf(stderr, "[%s]:[%s] - Cannot create semaphore female!\n",
- progname, strerror(errno), __func__);
- exit(EXIT_FAILURE);
- }
- if ((mutex_boy = sem_open("/mmux", O_CREAT,
- 0644, 1)) == SEM_FAILED) {
- fprintf(stderr, "[%s]:[%s] - Cannot create semaphore malemutex!\n",
- progname, strerror(errno), __func__);
- exit(EXIT_FAILURE);
- }
- if ((mutex_girl = sem_open("/fmux", O_CREAT,
- 0644, 1)) == SEM_FAILED) {
- fprintf(stderr, "[%s]:[%s] - Cannot create semaphore femalemutex!\n",
- progname, strerror(errno), __func__);
- exit(EXIT_FAILURE);
- }
- if ((new_person = sem_open("/new", O_CREAT,
- 0644, 1)) == SEM_FAILED) {
- fprintf(stderr, "[%s]:[%s] - Cannot create semaphore next!\n",
- progname, strerror(errno), __func__);
- exit(EXIT_FAILURE);
- }
- if ((empty = sem_open("/free", O_CREAT,
- 0644, 1)) == SEM_FAILED) {
- fprintf(stderr, "[%s]:[%s] - Cannot create semaphore empty!\n",
- progname, strerror(errno), __func__);
- exit(EXIT_FAILURE);
- }
- }
- void free_sem() {
- int err;
- err = sem_unlink("/m");
- /*if(err && errno != ENOSYS) {
- fprintf(stderr, "[%s]:[%s] - Cannot unlink semaphore: male %d \n",
- progname, strerror(errno), __func__, errno);
- exit(EXIT_FAILURE);
- }*/
- err = sem_unlink("/f");
- /*if(err && errno != ENOENT) {
- fprintf(stderr, "[%s]:[%s] - Cannot unlink semaphore: female\n",
- progname, strerror(errno), __func__);
- exit(EXIT_FAILURE);
- }*/
- err = sem_unlink("/mmux");
- /*if(err && errno != ENOENT) {
- fprintf(stderr, "[%s]:[%s] - Cannot unlink semaphore: malemutex\n",
- progname, strerror(errno), __func__);
- exit(EXIT_FAILURE);
- }*/
- err = sem_unlink("/fmux");
- /*if(err && errno != ENOENT) {
- fprintf(stderr, "[%s]:[%s] - Cannot unlink semaphore: femalemutex\n",
- progname, strerror(errno), __func__);
- exit(EXIT_FAILURE);
- }*/
- err = sem_unlink("/new");
- /*if(err && errno != ENOENT) {
- fprintf(stderr, "[%s]:[%s] - Cannot unlink semaphore: next\n",
- progname, strerror(errno), __func__);
- exit(EXIT_FAILURE);
- }*/
- err = sem_unlink("/free");
- /*if(err && errno != ENOENT) {
- fprintf(stderr, "[%s]:[%s] - Cannot unlink semaphore: empty\n",
- progname, strerror(errno), __func__);
- exit(EXIT_FAILURE);
- }*/
- }
- void finish() {
- int err;
- join_threads(20);
- err = sem_close(semaphore_m);
- if(err) {
- fprintf(stderr, "[%s]:[%s] - Cannot close semaphore: sem_m\n",
- progname, strerror(errno), __func__);
- exit(EXIT_FAILURE);
- }
- err = sem_close(semaphore_f);
- if(err) {
- fprintf(stderr, "[%s]:[%s] - Cannot close semaphore: sem_f\n",
- progname, strerror(errno), __func__);
- exit(EXIT_FAILURE);
- }
- err = sem_close(mutex_boy);
- if(err) {
- fprintf(stderr, "[%s]:[%s] - Cannot close semaphore: mutex_boy\n",
- progname, strerror(errno), __func__);
- exit(EXIT_FAILURE);
- }
- err = sem_close(mutex_girl);
- if(err) {
- fprintf(stderr, "[%s]:[%s] - Cannot close semaphore: mutex_girl\n",
- progname, strerror(errno), __func__);
- exit(EXIT_FAILURE);
- }
- err = sem_close(new_person);
- if(err) {
- fprintf(stderr, "[%s]:[%s] - Cannot close semaphore: new\n",
- progname, strerror(errno), __func__);
- exit(EXIT_FAILURE);
- }
- err = sem_close(empty);
- if(err) {
- fprintf(stderr, "[%s]:[%s] - Cannot close semaphore: empty\n",
- progname, strerror(errno), __func__);
- exit(EXIT_FAILURE);
- }
- free_sem();
- }
- int main() {
- srand((unsigned)time(NULL));
- char humans[20];
- free_sem();
- init_humans(humans);
- shuffle(humans, 20, sizeof(char));
- mk_sem();
- mk_threads(humans, 20);
- finish();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment