Skip to content
Snippets Groups Projects
Commit d145f55a authored by remi.greub's avatar remi.greub
Browse files

V1 dans repertoire séparé

parent 4c74ec39
No related branches found
No related tags found
No related merge requests found
{
"files.associations": {
"threads.h": "c"
}
}
\ No newline at end of file
CC:=gcc
CFLAGS:=-Wall -Wextra -pedantic -g -fsanitize=address,undefined -fsanitize-recover=address
LDFLAGS:=-lpthread -lm
EXEC:=bykes
ARGS:=10 100 10 10
$(EXEC): main.c
$(CC) $(CFLAGS) $^ -o $(EXEC) $(LDFLAGS)
clean:
rm -rf *.o $(EXEC)
run: $(EXEC)
./$< $(ARGS)
File added
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <semaphore.h>
#define TRUCK_CAPACITE_MAX 4
#define TRUCK_CAPACITE_TYP 2
#define CITY_CAPACITY_MIN 2
#define DEPOT 0
#define USLEEP 1
sem_t *sem_FreeSlot;
sem_t *sem_BikeFree;
pthread_mutex_t *mutex;
pthread_barrier_t b;
int personsFinished=0;
struct person{
int num_thread;
int nb_travels;
int max_travels;
int i_terminals;
int nbterminals;
int nslots;
};
struct Truck{
int num_thread;
int n_bike;
int i_terminals;
int nbterminals;
int nslots;
int nbpersons;
};
struct city{
int nb_bikesParked;
int nb_P_waiting;
};
int rand_Dc();
int rand_D();
//void persons_PassiveMode(void *arg);
void *trucks(void *arg);
void *Persons(void *arg);
struct city *terminals; //this table is the size of the number of terminals, each terminals has NParkinglot and each numbers represents a free parkinglot
int main(int argc, char **argv){
if (argc < 5 || argc > 5){
perror("erreur d'arguments d'entrée\n");
return EXIT_FAILURE;
}
int nbterminals = atoi(argv[1]); //S 10
int nbpersons = atoi(argv[2]); //H 100
int nbtravels = atoi(argv[3]); //M 10
int nbslots = atoi(argv[4]); //N 10
nbterminals += 1;
srand(0);
pthread_t *threadpersons = malloc(sizeof(pthread_t)*nbpersons);
pthread_t *threadTruck = malloc(sizeof(pthread_t));
terminals = calloc(nbterminals, sizeof(struct city));
struct person *persons = calloc(nbpersons, sizeof(struct person));
struct Truck *truck = malloc(sizeof(struct Truck));
for(int j = 0; j<nbterminals; j++){
terminals[j].nb_bikesParked = nbslots-2;
terminals[j].nb_P_waiting = 0;
}
terminals[DEPOT].nb_bikesParked = 0;
truck->i_terminals = 0;
truck->n_bike = TRUCK_CAPACITE_TYP;
truck->nslots = nbslots;
truck->num_thread = nbpersons;
truck->nbterminals = nbterminals;
truck->nbpersons = nbpersons;
sem_BikeFree = malloc(sizeof(sem_t)*nbterminals);
sem_FreeSlot = malloc(sizeof(sem_t)*nbterminals);
mutex = malloc(sizeof(pthread_mutex_t)*nbterminals);
for(int x =0; x<nbterminals; x++){
sem_init(&sem_BikeFree[x], 0, nbslots-2);//8);
sem_init(&sem_FreeSlot[x], 0, nbslots-(nbslots-2));//2);
pthread_mutex_init(&mutex[x], NULL); //mutex du truck
}
pthread_barrier_init(&b, NULL, nbpersons);
if(pthread_create(threadTruck, NULL, trucks, (void*)truck)!=0){
perror("thread creation error");
return EXIT_FAILURE;
}
for(int i=0; i<nbpersons; i++){
persons[i].max_travels = nbtravels;
persons[i].nslots = nbslots;
persons[i].nbterminals = nbterminals;
persons[i].num_thread = i;
persons[i].nb_travels = 0;
persons[i].i_terminals = (rand()%(persons[i].nbterminals - 1))+1;
if(pthread_create(&threadpersons[i], NULL, Persons, (void*)&persons[i])!=0){
perror("thread creation error");
return EXIT_FAILURE;
}
}
//pthread_barrier_wait(&b);
if(pthread_join(*threadTruck, NULL)){
perror("thread join error");
return EXIT_FAILURE;
}
//thread join
for(int i=0; i<nbpersons; i++){
if(pthread_join(threadpersons[i], NULL)){
perror("thread join error");
return EXIT_FAILURE;
}
}
printf("***************** CYCLING TERMINATED ***************\n");
int sum=0;
for(int i=1; i<nbterminals; i++){
printf("Terminal %d contains %d bikes\n", i, terminals[i].nb_bikesParked);
sum+=terminals[i].nb_bikesParked;
}
printf("total number of bikes in town: %d, in depot: %d, in truck: %d, total: %d\n", sum, terminals[DEPOT].nb_bikesParked, truck->n_bike, truck->n_bike+terminals[DEPOT].nb_bikesParked+sum);
//free the memory
for(int i=0; i<nbterminals; i++){
sem_destroy(&sem_BikeFree[i]);
sem_destroy(&sem_FreeSlot[i]);
pthread_mutex_destroy(&mutex[i]);
}
pthread_barrier_destroy(&b);
free(threadpersons);
free(threadTruck);
free(sem_BikeFree);
free(sem_FreeSlot);
free(mutex);
free(persons);
free(truck);
free(terminals);
return EXIT_SUCCESS;
}
void *Persons(void *arg){
struct person *hab = (struct person*)arg;
int j=0;
int val;
// inside a Mtravels loop for each persons
while(hab->nb_travels < hab->max_travels){
//waits for a bike in terminals i
//if(hab->i_terminals==4){
sem_getvalue(&sem_FreeSlot[hab->i_terminals],&val);
pthread_mutex_lock(&mutex[hab->i_terminals]);
printf("(GET) person %d starts from terminal %d (%d bykes, %d persons waiting, semslotsFree_val : %d)\n", hab->num_thread, hab->i_terminals, terminals[hab->i_terminals].nb_bikesParked, terminals[hab->i_terminals].nb_P_waiting, val);//terminals[hab->i_terminals].nb_P_waiting);
pthread_mutex_unlock(&mutex[hab->i_terminals]);
//}
if(terminals[hab->i_terminals].nb_bikesParked<=0){// && hab->i_terminals == 4){
printf("person %d is STUCK at terminal %d: rack empty : %d bikes\n", hab->num_thread, hab->i_terminals, terminals[hab->i_terminals].nb_bikesParked);
}
pthread_mutex_lock(&mutex[hab->i_terminals]);
terminals[hab->i_terminals].nb_P_waiting += 1;
pthread_mutex_unlock(&mutex[hab->i_terminals]);
sem_wait(&sem_BikeFree[hab->i_terminals]);
pthread_mutex_lock(&mutex[hab->i_terminals]);
terminals[hab->i_terminals].nb_P_waiting -= 1;
terminals[hab->i_terminals].nb_bikesParked -= 1; //critical section
//if(hab->i_terminals==4){
//printf("person %d leaves terminal %d by bike\n", hab->num_thread, hab->i_terminals);
//}
pthread_mutex_unlock(&mutex[hab->i_terminals]);
sem_post(&sem_FreeSlot[hab->i_terminals]);
//if(hab->i_terminals==4){
printf("person %d leaves terminal %d by bike\n", hab->num_thread, hab->i_terminals);
//}
//go to place j = rand()%nterminals and j != i
do{
j = (rand()%(hab->nbterminals - 1))+1;
}while(j==hab->i_terminals);
#if USLEEP
usleep(rand_D());
#endif
//waits for a parkinglot to be freed and deposit his bycycle
//if(j==4){
sem_getvalue(&sem_BikeFree[j],&val);
pthread_mutex_lock(&mutex[j]);
printf("(PUT) person %d arrives at terminal %d (%d bykes, %d persons waiting, semBikeFree_val : %d)\n", hab->num_thread, j, terminals[j].nb_bikesParked, terminals[j].nb_P_waiting, val);//terminals[j].nb_P_waiting);
pthread_mutex_unlock(&mutex[j]);
//}
if(terminals[j].nb_bikesParked>=hab->nslots){//} && j == 4){
printf("person %d is STUCK at terminal %d: rack full : %d bikes\n", hab->num_thread, j, terminals[j].nb_bikesParked);
}
pthread_mutex_lock(&mutex[j]);
terminals[j].nb_P_waiting += 1;
pthread_mutex_unlock(&mutex[j]);
sem_wait(&sem_FreeSlot[j]);
pthread_mutex_lock(&mutex[j]);
//deposit his bycycle
terminals[j].nb_P_waiting -= 1;
terminals[j].nb_bikesParked += 1; //critical section
pthread_mutex_unlock(&mutex[j]);
sem_post(&sem_BikeFree[j]);
//if(j==4){
printf("person %d leaves terminal %d by foot\n", hab->num_thread, j);
//}
//does whatever he has to do for a D delay time (waits for rand() 1000->1999us)
#if USLEEP
usleep(rand_D());
#endif
//changes his position from terminals i = j (j is the new terminals)
hab->i_terminals = j;
hab->nb_travels += 1;
}
printf("person %d stops\n", hab->num_thread);
pthread_mutex_lock(&mutex[hab->i_terminals]);
personsFinished += 1;
pthread_mutex_unlock(&mutex[hab->i_terminals]);
pthread_barrier_wait(&b);
//printf("machin bidule a passé la barriere !!!! : %d, tot_travels = %d\n", hab->num_thread, hab->nb_travels);
return NULL;
}
void *trucks(void *arg){
struct Truck *truck = (struct Truck*)arg;
int tmp_nbBikes;
while(personsFinished < truck->nbpersons){
//1 : for each terminals from 1 to S (0 is the depot)
for(int i=1; i<truck->nbterminals; i++){
//spreads the bikes evenly
//too many bikes in this terminals
tmp_nbBikes = truck->n_bike;
if(terminals[i].nb_bikesParked > (truck->nslots-2) && truck->n_bike < TRUCK_CAPACITE_MAX){
while(terminals[i].nb_bikesParked > (truck->nslots-2) && truck->n_bike < TRUCK_CAPACITE_MAX){
sem_wait(&sem_BikeFree[i]);
pthread_mutex_lock(&mutex[i]);
truck->n_bike += 1;
terminals[i].nb_bikesParked -= 1;
pthread_mutex_unlock(&mutex[i]);
sem_post(&sem_FreeSlot[i]);
}
pthread_mutex_lock(&mutex[i]);
printf("truck removes %d bikes at terminal %d (%d bikes, %d persons waiting, %d left in truck)\n", truck->n_bike-tmp_nbBikes, i, terminals[i].nb_bikesParked, terminals[i].nb_P_waiting, truck->n_bike);
pthread_mutex_unlock(&mutex[i]);
}
// not enough bikes in this terminals
// until he gets at least 2 bikes (or the truck is empty)
else if(terminals[i].nb_bikesParked < CITY_CAPACITY_MIN && truck->n_bike > 0){
tmp_nbBikes = truck->n_bike;
while(terminals[i].nb_bikesParked < CITY_CAPACITY_MIN && truck->n_bike > 0){
sem_wait(&sem_FreeSlot[i]);
pthread_mutex_lock(&mutex[i]);
truck->n_bike -= 1;
terminals[i].nb_bikesParked += 1;
pthread_mutex_unlock(&mutex[i]);
sem_post(&sem_BikeFree[i]);
}
pthread_mutex_lock(&mutex[i]);
printf("truck adds %d bikes at terminal %d (%d bikes, %d persons waiting, %d left in truck)\n", tmp_nbBikes-truck->n_bike, i, terminals[i].nb_bikesParked, terminals[i].nb_P_waiting, truck->n_bike);
pthread_mutex_unlock(&mutex[i]);
}
}
//2: goes to the depot to rebalance the truck's content to 2 bycycles
tmp_nbBikes = truck->n_bike;
if(truck->n_bike < TRUCK_CAPACITE_TYP){
if(terminals[DEPOT].nb_bikesParked > 0){
while(truck->n_bike < TRUCK_CAPACITE_TYP && terminals[DEPOT].nb_bikesParked > 0){
truck->n_bike += 1;
pthread_mutex_lock(&mutex[DEPOT]);
terminals[DEPOT].nb_bikesParked -= 1;
pthread_mutex_unlock(&mutex[DEPOT]);
}
pthread_mutex_lock(&mutex[DEPOT]);
printf("(DEPOT) truck gets %d bikes at terminal %d (%d bikes, %d persons waiting, %d left in truck)\n", truck->n_bike-tmp_nbBikes, DEPOT, terminals[DEPOT].nb_bikesParked, terminals[DEPOT].nb_P_waiting, truck->n_bike);
pthread_mutex_unlock(&mutex[DEPOT]);
}
}
else if (truck->n_bike > TRUCK_CAPACITE_TYP){
while(truck->n_bike > TRUCK_CAPACITE_TYP){
truck->n_bike -= 1;
pthread_mutex_lock(&mutex[DEPOT]);
terminals[DEPOT].nb_bikesParked += 1;
pthread_mutex_unlock(&mutex[DEPOT]);
}
pthread_mutex_lock(&mutex[DEPOT]);
printf("(DEPOT) truck deposit %d bikes at terminal %d (%d bikes, %d persons waiting, %d left in truck)\n", tmp_nbBikes-truck->n_bike, DEPOT, terminals[DEPOT].nb_bikesParked, terminals[DEPOT].nb_P_waiting, truck->n_bike);
pthread_mutex_unlock(&mutex[DEPOT]);
}
//3: pause betweem 100us up to 199us
#if USLEEP
usleep(rand_Dc());
#endif
//printf("TRUCK new loop, person's threads finished: %d\n", personsFinished);
}
printf("TRUCK end loop\n");
return NULL;
}
int rand_D(){
return (rand()%999)+1000;
}
int rand_Dc(){
return (rand()%99)+100;
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment