-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c7cca17
commit 8f19b33
Showing
10 changed files
with
1,330 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
//Abhishek Rathod B.Tech IIT Roorkee CSE | ||
// Enroll. No.- 17114004 | ||
|
||
#include <stdlib.h> | ||
#include <stdio.h> | ||
#include <pthread.h> | ||
#include "my_semaphore.h" | ||
#include <stdbool.h> | ||
#include <errno.h> | ||
#include <unistd.h> | ||
|
||
sem_t smokers[3]; | ||
sem_t smoker_agent; | ||
|
||
typedef void *(*smokers_t)(void *); | ||
|
||
static int totalcount=20 ; //total number of times smokers will smoke a cigarette | ||
|
||
|
||
// Assuming all the three smokers have an infinite supply of paper | ||
|
||
void* smoker_1(void* arg) | ||
{ | ||
while (totalcount>0) | ||
{ | ||
nanosleep((struct timespec[]){{0, rand() % 100000000}}, NULL); | ||
printf("Smoker one is waiting to smoke.\n"); | ||
|
||
sem_wait(&smokers[0]); | ||
printf("Smoker one received matches and tobacco and is now making cigarette.\n"); | ||
sem_post(&smoker_agent); | ||
totalcount-- ; | ||
} | ||
if(totalcount==0){ | ||
exit(0) ; | ||
} | ||
return NULL; | ||
} | ||
|
||
void* smoker_2(void* arg) | ||
{ | ||
while (totalcount>0) | ||
{ | ||
nanosleep((struct timespec[]){{0, rand() % 100000000}}, NULL); | ||
printf("Smoker two is waiting to smoke.\n"); | ||
|
||
sem_wait(&smokers[1]); | ||
printf("Smoker two received matches and tobacco and is now making cigarette.\n"); | ||
sem_post(&smoker_agent); | ||
totalcount-- ; | ||
} | ||
if(totalcount==0){ | ||
exit(0) ; | ||
} | ||
return NULL; | ||
} | ||
|
||
void* smoker_3(void* arg) | ||
{ | ||
while (totalcount>0) | ||
{ | ||
nanosleep((struct timespec[]){{0, rand() % 100000000}}, NULL); | ||
printf("Smoker three is waiting to smoke (has tobacco)\n"); | ||
|
||
sem_wait(&smokers[2]); | ||
printf("Smoker three received matches and tobacco and is now making cigarette.\n"); | ||
sem_post(&smoker_agent); | ||
totalcount-- ; | ||
} | ||
if(totalcount==0){ | ||
exit(0) ; | ||
} | ||
return NULL; | ||
} | ||
|
||
|
||
// The main thread handles the agent's abritatin of items. | ||
|
||
int main(int argc, char* arvg[]) | ||
{ | ||
srand(time(NULL)); | ||
|
||
// Initalize agent semaphore | ||
sem_init(&smoker_agent, 0, 1); | ||
|
||
// Setup our smoker threads and function references | ||
pthread_t smoker_threads[3]; | ||
smokers_t smoker_functions[3] = { smoker_1, smoker_2, smoker_3 }; | ||
|
||
// Create the smoker threads and initalize the semaphores | ||
for (int i = 0; i < 3; ++i) | ||
{ | ||
sem_init(&smokers[i], 0, 0); | ||
|
||
if(pthread_create(&smokers[i], NULL, smoker_functions[i], NULL) == EAGAIN) | ||
{ | ||
perror("Insufficent resources to create thread.\n"); | ||
return 0; | ||
} | ||
} | ||
|
||
// Agent begins to distribute his items | ||
while (1) | ||
{ | ||
// Lock the agent | ||
sem_wait(&smoker_agent); | ||
|
||
// Distribute two items for one of the smokers | ||
sem_post(&smokers[rand() % 3]); | ||
} | ||
|
||
// Join all of the smoker threads on exit | ||
for (int i = 0; i < 3; ++i) | ||
{ | ||
pthread_join(smoker_threads[i], NULL); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
//Abhishek Rathod B.Tech IIT Roorkee CSE | ||
// Enroll. No.- 17114004 | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <stdatomic.h> | ||
#include <pthread.h> | ||
|
||
typedef struct | ||
{ | ||
pthread_cond_t* element; | ||
struct node* next; | ||
}node; // struct for each element in queue of a semaphore | ||
|
||
typedef struct | ||
{ | ||
node* head; | ||
node* tail; | ||
pthread_mutex_t queue_mutex; | ||
int len; | ||
|
||
}queue; // struct for the queue in the semaphore | ||
|
||
void insert_element(queue *q, pthread_cond_t* val) | ||
{ | ||
node* reg=(node*)malloc(sizeof(node)); | ||
reg->element=val; | ||
if(q->head==NULL) | ||
{ | ||
q->head=reg; | ||
q->tail=reg; | ||
q->len=1; | ||
} | ||
else | ||
{ | ||
q->tail->next=reg; | ||
q->tail=reg; | ||
q->len++; | ||
} | ||
} | ||
|
||
|
||
|
||
pthread_cond_t* remove_element(queue *q) | ||
{ | ||
if(q->len<=0) | ||
{ | ||
pthread_mutex_unlock(&q->queue_mutex); | ||
return NULL; | ||
} | ||
else | ||
{ | ||
pthread_cond_t* return_ele=q->head->element; | ||
if(q->len==1) | ||
{ | ||
q->head=NULL; | ||
q->tail=NULL; | ||
q->len=0; | ||
} | ||
else | ||
{ | ||
q->len--; | ||
q->head=q->head->next; | ||
} | ||
pthread_mutex_unlock(&q->queue_mutex); | ||
|
||
return return_ele; | ||
} | ||
|
||
return NULL; | ||
} | ||
|
||
void push(queue* q ,pthread_cond_t* val) | ||
{ | ||
pthread_mutex_lock(&q->queue_mutex); | ||
|
||
insert_element(q, val) ; | ||
|
||
pthread_mutex_unlock(&q->queue_mutex); | ||
} | ||
|
||
|
||
pthread_cond_t* pop(queue* q) | ||
{ | ||
pthread_mutex_lock(&q->queue_mutex); | ||
|
||
pthread_cond_t* return_ele=remove_element(q) ; | ||
|
||
return return_ele; | ||
} | ||
|
||
|
||
|
||
typedef struct | ||
{ | ||
atomic_int s; // semaphore varible | ||
queue Q; // queue for storing blocked threads | ||
pthread_mutex_t lock1; | ||
pthread_mutex_t lock2; | ||
|
||
} sem_t; // semaphore struct | ||
|
||
|
||
|
||
void sem_init( sem_t* reg,int pshared,unsigned int element) // for semaphore inilization | ||
{ | ||
reg->s=element; // assign value | ||
// thread_mutex_t lock1 = PTHREAD_MUTEX_INITIALIZER; | ||
} | ||
|
||
|
||
void sem_wait(sem_t* reg) // same AS wait(S) | ||
{ | ||
pthread_mutex_lock(®->lock1); // saving from other threads | ||
reg->s--; | ||
if(reg->s<0) | ||
{ | ||
pthread_cond_t* cond_reg=(pthread_cond_t*)malloc(sizeof(pthread_cond_t)); | ||
push(®->Q,cond_reg); | ||
pthread_cond_wait(cond_reg,®->lock1); //block(reg) blocking reg thread | ||
|
||
|
||
} | ||
|
||
pthread_mutex_unlock(®->lock1); | ||
|
||
|
||
} | ||
|
||
void sem_post(sem_t* reg) | ||
{ | ||
pthread_mutex_lock(®->lock2); // saving from other threads | ||
|
||
reg->s++; | ||
if(reg->s<=0) | ||
{ | ||
|
||
pthread_cond_t* cond=pop(®->Q); | ||
if(cond!=NULL) | ||
{ | ||
pthread_cond_signal(cond); // wake up (selected thread) | ||
} | ||
|
||
} | ||
pthread_mutex_unlock(®->lock2); | ||
|
||
} |
Oops, something went wrong.