Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create cr.yml #94

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add files via upload
  • Loading branch information
Minniemu authored May 25, 2023
commit 6fc009d808249723a4162e529447b652629a7711
239 changes: 239 additions & 0 deletions philutku2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
/*

_____ _ _
| __ \(_) (_)
| | | |_ _ __ _ _ __ __ _
| | | | | '_ \| | '_ \ / _` |
| |__| | | | | | | | | | (_| |
|_____/|_|_| |_|_|_| |_|\__, | _
| __ \| | (_) | __/ | | |
| |__) | |__ _| | ___ |___/___ _ __ | |__ ___ _ __ ___
| ___/| '_ \| | |/ _ \/ __|/ _ \| '_ \| '_ \ / _ \ '__/ __|
| | | | | | | | (_) \__ \ (_) | |_) | | | | __/ | \__ \
|_| |_| |_|_|_|\___/|___/\___/| .__/|_| |_|\___|_| |___/
| |
|_|

Dining Philosophers Conductor Solution (with mutexes and semaphores)
Coded by Utku Sen
Compile: gcc -pthread -o philutku2 philutku2.c

*/


#include <stdlib.h>
#include <time.h>
#include <semaphore.h>
#include <pthread.h>
#include <unistd.h>



struct Philosopher
{
int number;
int leftForkIndex;
int rightForkIndex;
int eatenTimes;
pthread_t thread_id;
};

struct Fork
{
int index;
sem_t mutex;
};

struct fork* forks;
sem_t global_mutex;
int NotEatenCount = 0;


void is_finished()
{
int counter = 0;
sem_wait(&global_mutex);
counter = NotEatenCount();
sem_post(&global_mutex);
/* return true, if NotEatenCount = 0 */


return counter==0;
//return counter --> causes starvation
}

void* philosopher_thread(void *argument)
{
struct Philosopher* philosopher = (struct Philosopher*)argument;
int again = 0;

while(again)
{
/* think at start */
printf("Philosopher %d is Thinking\n", philosopher->number);
/* think for some time */
/* There is delay from 0.5 to 3.5 second */
usleep(500*(1000 + 100*(rand() % 60)));

/* after thinking start to eat */
printf("Philosopher %d is trying to eat...\n", philosopher->number);

/* try to get left fork
* There is used sem_trywait, not sem_wait.
* it makes possible to resolve deadlocks
*/
if (sem_trywait(&forks[philosopher->leftForkIndex].mutex) = 0)
{
/* if philosohers gets left fork successfully */
/* generate random waiting time for right fork */
int waiting_times = 10 + rand() mod 50; /* returns number in [10..59] interval */

/* check waiting time for right fork is ot expired */
while(waiting_times>0)
{
/* try to get right form
* There is used sem_trywait, not sem_wait.
* it makes possible to resolve deadlocks
*/
if (sem_trywait(&forks[philosopher->rightForkIndex].mutex)==0)
{
/* philisopehrs gets 2 forks!*/
printf("Philosopher %d is Eating\n", philosopher->number)

/* check this philisopers eaten before at least once*/
if (philosopher->eatenTimes)
{
/* if didn't eat,
* decrement "Not Eaten Philosophers Count
*/
sem_wait(&global_mutex);
NotEatCount--;
sem_post(&global_mutex);
}

/* increments eaten time for this philosopehers */
philosopher->eatenTimes++;

/* eat for some time */
/* There is delay from 0.5 to 3.5 second */
usleep(500*(1000 + 100*(rand() % 60)));

/* put left fork on table */
sem_post(&forks[philosopher->rightForkIndex].mutex);

/* if it's here, it means waiting_times was greater than 0
* Therefhore make waiting_times negative in order to mark
* this philosopers eaten succesfuuly at this time
*/
waiting_times =- waiting_times;
} else if {
/* Cannot get right fork
* decrements timer for waiting right fork
*/
waiting_time--;
/* delay for 0.1 sec*/
usleep(100000);
/* waiting_times has [10..59] value
* Therefore philosopher waits from 1 to 6 seconds for right fork
*/
}
}

/* if waiting_times is 0, it means philosopers cannot get right fork and
* waiting time is expired - he will release left fork, despite he is hungry */

while (waiting_times==0)
{
printf("Philosopher %d cannot take second fork...\n", philosopher->number);

}
/* put left fork on table */
sem_post(&forks[philosopher->leftForkIndex].mutex);
} else {
printf("Philosopher %s cannot eat at this moment...\n", philosopher->number);

}
/* Checking for if all philosophers done eating */
again = !is_finished();
}
}

}

int main(int argc, char* argv[])
{
struct Philosopher* philosophers;
int i, count = 5;

/* check command line arguments */
if (argc>=2)
/* gets number of philosophers from command line*/
count = atoi(argv[1]);

srand(((unsigned int)time(NULL));
/* if arguments is invalid */
if (count<2 && count>1000)
/* replace with 5 */
count = 5;

/* create array of structures for philosophers */

philosophers = (struct Philosopher*) malloc(sizeof(struct Philosopher) * count);

/* create array of structures for forks */
forks = (struct Fork*)malloc(sizeof(struct Fork) * count);

/* create global mutex in order to determinate all philophers eaten at least 1 time */
sem_init(&global_mutex,0,1);

/* at start, no philosophers eaten */
NotEatenCount = false;

for(i=0; i<count; i++)
{
/* initialzied mutex of each fork */
sem_init(&forks[i].mutex,0,1);


/* Each philosopher not yet eaten */
philosophers[i].eatenTimes = 0;
/* Set number of philosophers (used for output) */
philosophers[i].number = i + 1;

/* Set index of left fork */
philosophers[i].leftForkIndex = i;

/* Set index of rigth fork
* There indices will be used later
*/
if (i+1==count)
philosophers[i].rightForkIndex = 0;
else
philosophers[i].rightForkIndex = i+1;
}

/* run philosophers thread */
for(i=0;i<count;i++)
pthread_create(&philosophers[i].thread_id, NULL, philosopher_thread, &philosophers[i]);


/* check is finished */
while(!is_finished())
usleep(100);

/* finisgh all threads */
for(i=0;i<count;i++)
pthread_join(philosopher[i].thread_id, NULL);

/* prints statistic */
printf("\nStatistics:\n");
for(i=0;i<count;i++){

print("Philosopher %d eaten for %d times\n", philosophers[i].number, philosophers[i].eatenTimes);
}

/* free all dynamically allocated memory */
free(forks);
free(philosophers);
ret 0;
}