Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • main
1 result

Target

Select target project
  • remi.greub/g17_bykes_prog_concurrente
1 result
Select Git revision
  • main
1 result
Show changes
Commits on Source (2)
*.o
\ No newline at end of file
{
"files.associations": {
"stdlib.h": "c",
"threads.h": "c",
"unistd.h": "c"
}
}
\ No newline at end of file
{
"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 CAMION_CAPACITE_MAX 4
#define CAMION_CAPACITE_TYP 2
#define SITE_CAPACITE_MIN 2
//#define NUM_THREAD 5
#define DEPOT 0
sem_t *sem_BorneFree;
sem_t *sem_BikeFree;
pthread_mutex_t *mutex;
pthread_barrier_t b;
bool end = false;
struct habitant{
int num_thread;
int nb_trajet;
int max_trajets;
int i_site;
int nbSites;
int nbornes;
};
struct camionette{
int num_thread;
int n_Velo;
int i_site;
int nbSites;
int nbornes;
};
struct site{
int nb_bikesParked;
int nb_P_waiting;
};
int rand_Dc();
int rand_D();
//void habitants_PassiveMode(void *arg);
void *Camion(void *arg);
void *habitants(void *arg);
struct site *sites; //this table is the size of the number of sites, each sites 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 nbSites = atoi(argv[1]); //S 10
int nbHabs = atoi(argv[2]); //H 100
int nbTrajets = atoi(argv[3]); //M 10
int nbBorne = atoi(argv[4]); //N 10
srand(0);
pthread_t *threadHabs = malloc(sizeof(pthread_t)*nbHabs);
pthread_t *threadCam = malloc(sizeof(pthread_t));
sites = calloc(nbSites, sizeof(struct site));
struct habitant *habs = calloc(nbHabs, sizeof(struct habitant));
struct camionette *camion = malloc(sizeof(struct camionette));
for(int j = 0; j<nbSites; j++){
sites[j].nb_bikesParked = nbBorne-2;
sites[j].nb_P_waiting = 0;
}
sites[0].nb_bikesParked = 0; //depot avec 0 velos au depart
camion->i_site = 0;
camion->n_Velo = CAMION_CAPACITE_TYP;
camion->nbornes = nbBorne;
camion->num_thread = nbHabs;
camion->nbSites = nbSites;
sem_BikeFree = malloc(sizeof(sem_t)*nbSites);
sem_BorneFree = malloc(sizeof(sem_t)*nbSites);
//mutex = malloc(sizeof(pthread_mutex_t)*(nbHabs+1));
mutex = malloc(sizeof(pthread_mutex_t)*nbSites);
for(int x =0; x<nbSites; x++){
sem_init(&sem_BikeFree[x], 0, 8);
sem_init(&sem_BorneFree[x], 0, 2);
pthread_mutex_init(&mutex[x], NULL); //mutex du camion
}
pthread_barrier_init(&b, NULL, nbHabs);
if(pthread_create(threadCam, NULL, Camion, (void*)camion)!=0){
perror("thread creation error");
return EXIT_FAILURE;
}
for(int i=0; i<nbHabs; i++){
habs[i].max_trajets = nbTrajets;
habs[i].nbornes = nbBorne;
habs[i].nbSites = nbSites;
habs[i].num_thread = i;
habs[i].nb_trajet = 0;
habs[i].i_site = (rand()%(habs[i].nbSites - 1))+1;
pthread_mutex_init(&mutex[i], NULL); //mutex par habitants
if(pthread_create(&threadHabs[i], NULL, habitants, (void*)&habs[i])!=0){
perror("thread creation error");
return EXIT_FAILURE;
}
}
//pthread_barrier_wait(&b);
if(pthread_join(*threadCam, NULL)){ // va retourner un truc après
perror("thread join error");
return EXIT_FAILURE;
}
//thread join
for(int i=0; i<nbHabs; i++){
if(pthread_join(threadHabs[i], NULL)){ //va retourner un truc après
perror("thread join error");
return EXIT_FAILURE;
}
}
//free the memory
for(int i=0; i<nbSites; i++){
sem_destroy(&sem_BikeFree[i]);
sem_destroy(&sem_BorneFree[i]);
}
for(int i=0; i<nbHabs+1; i++){
pthread_mutex_destroy(&mutex[i]);
}
pthread_barrier_destroy(&b);
free(threadHabs);
free(threadCam);
free(sem_BikeFree);
free(sem_BorneFree);
free(mutex);
int sum=0;
for(int i=0; i<nbSites; i++){
sum+=sites[i].nb_bikesParked;
}
printf("nb de velos en fin de programme %d\n", sum);
free(habs);
free(camion);
free(sites);
//srand(time(NULL));
//nb sites, nb habs, nb de voyaegs par habitants, nb de bornes par sites
return EXIT_SUCCESS;
}
void *habitants(void *arg){
struct habitant *hab = (struct habitant*)arg;
int j=0;
int val;
// inside a Mtrajets loop for each habitants
while(hab->nb_trajet < hab->max_trajets){
//waits for a bike in site i
//if(hab->i_site==4){
pthread_mutex_lock(&mutex[hab->i_site]);
printf("(GET) person %d starts from terminal %d (%d bykes, %d persons waiting, semVal : %d)\n", hab->num_thread, hab->i_site, sites[hab->i_site].nb_bikesParked, sites[hab->i_site].nb_P_waiting, val);//sites[hab->i_site].nb_P_waiting);
pthread_mutex_unlock(&mutex[hab->i_site]);
//}
sem_getvalue(&sem_BorneFree[hab->i_site],&val);
if(sites[hab->i_site].nb_bikesParked<=0){// && hab->i_site == 4){
printf("person %d is STUCK at terminal %d: rack empty with : %d bikes\n", hab->num_thread, hab->i_site, sites[hab->i_site].nb_bikesParked);
}
pthread_mutex_lock(&mutex[hab->i_site]);
sites[hab->i_site].nb_P_waiting += 1;
pthread_mutex_unlock(&mutex[hab->i_site]);
sem_wait(&sem_BikeFree[hab->i_site]);
pthread_mutex_lock(&mutex[hab->i_site]);
sites[hab->i_site].nb_P_waiting -= 1;
sites[hab->i_site].nb_bikesParked -= 1; //critical section
//if(hab->i_site==4){
//printf("person %d leaves terminal %d by bike\n", hab->num_thread, hab->i_site);
//}
pthread_mutex_unlock(&mutex[hab->i_site]);
sem_post(&sem_BorneFree[hab->i_site]);
//if(hab->i_site==4){
printf("person %d leaves terminal %d by bike\n", hab->num_thread, hab->i_site);
//}
//go to place j = rand()%nsites and j != i
do{
j = (rand()%(hab->nbSites - 1))+1;
}while(j==hab->i_site);
usleep(rand_D());
//waits for a parkinglot to be freed and deposit his bycycle
//if(j==4){
pthread_mutex_lock(&mutex[j]);
printf("(PUT) person %d arrives at terminal %d (%d bykes, %d persons waiting, semVal : %d)\n", hab->num_thread, j, sites[j].nb_bikesParked, sites[j].nb_P_waiting, val);//sites[j].nb_P_waiting);
pthread_mutex_unlock(&mutex[j]);
//}
sem_getvalue(&sem_BikeFree[j],&val);
if(sites[j].nb_bikesParked>=hab->nbornes){//} && j == 4){
printf("person %d is STUCK at terminal %d: rack full : %d bikes\n", hab->num_thread, j, sites[j].nb_bikesParked);
}
pthread_mutex_lock(&mutex[j]);
sites[j].nb_P_waiting += 1;
pthread_mutex_unlock(&mutex[j]);
sem_wait(&sem_BorneFree[j]);
pthread_mutex_lock(&mutex[j]);
//deposit his bycycle
sites[j].nb_P_waiting -= 1;
sites[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)
usleep(rand_D());
//changes his position from site i = j (j is the new site)
hab->i_site = j;
hab->nb_trajet += 1;
}
//printf("machin bidule finished : %d, tot_trajets = %d\n", hab->num_thread, hab->nb_trajet);
pthread_barrier_wait(&b);
//printf("machin bidule a passé la barriere !!!! : %d, tot_trajets = %d\n", hab->num_thread, hab->nb_trajet);
pthread_mutex_lock(&mutex[hab->i_site]);
end = true;
pthread_mutex_unlock(&mutex[hab->i_site]);
return NULL;
}
void *Camion(void *arg){
struct camionette *camion = (struct camionette*)arg;
int tmp_nbBikes;
while(!end){
//1 : for each sites from 1 to S (0 is the depot)
for(int i=1; i<camion->nbSites; i++){
//spreads the bikes evenly
//too many bikes in this site
tmp_nbBikes = camion->n_Velo;
if(sites[i].nb_bikesParked > (camion->nbornes-2) && camion->n_Velo < CAMION_CAPACITE_MAX){
while(sites[i].nb_bikesParked > (camion->nbornes-2) && camion->n_Velo < CAMION_CAPACITE_MAX){
sem_wait(&sem_BikeFree[i]);
pthread_mutex_lock(&mutex[i]);
camion->n_Velo += 1;
sites[i].nb_bikesParked -= 1;
pthread_mutex_unlock(&mutex[i]);
sem_post(&sem_BorneFree[i]);
}
pthread_mutex_lock(&mutex[i]);
printf("truck removes %d bikes at terminal %d (%d bikes, %d persons waiting, %d left in truck)\n", camion->n_Velo-tmp_nbBikes, i, sites[i].nb_bikesParked, sites[i].nb_P_waiting, camion->n_Velo);
pthread_mutex_unlock(&mutex[i]);
}
// not enough bikes in this site
// until he gets at least 2 bikes (or the camion is empty)
else if(sites[i].nb_bikesParked < SITE_CAPACITE_MIN && camion->n_Velo > 0){
tmp_nbBikes = camion->n_Velo;
while(sites[i].nb_bikesParked < SITE_CAPACITE_MIN && camion->n_Velo > 0){
sem_wait(&sem_BorneFree[i]);
pthread_mutex_lock(&mutex[i]);
camion->n_Velo -= 1;
sites[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-camion->n_Velo, i, sites[i].nb_bikesParked, sites[i].nb_P_waiting, camion->n_Velo);
pthread_mutex_unlock(&mutex[i]);
}
}
//2: goes to the depot to rebalance the truck's content to 2 bycycles
tmp_nbBikes = camion->n_Velo;
if(camion->n_Velo < CAMION_CAPACITE_TYP){
if(sites[DEPOT].nb_bikesParked > 0){
while(camion->n_Velo < CAMION_CAPACITE_TYP && sites[DEPOT].nb_bikesParked > 0){
camion->n_Velo += 1;
pthread_mutex_lock(&mutex[DEPOT]);
sites[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", camion->n_Velo-tmp_nbBikes, DEPOT, sites[DEPOT].nb_bikesParked, sites[DEPOT].nb_P_waiting, camion->n_Velo);
pthread_mutex_unlock(&mutex[DEPOT]);
}
}
else if (camion->n_Velo > CAMION_CAPACITE_TYP){
while(camion->n_Velo > CAMION_CAPACITE_TYP){
camion->n_Velo -= 1;
pthread_mutex_lock(&mutex[DEPOT]);
sites[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-camion->n_Velo, DEPOT, sites[DEPOT].nb_bikesParked, sites[DEPOT].nb_P_waiting, camion->n_Velo);
pthread_mutex_unlock(&mutex[DEPOT]);
}
//3: pause betweem 100us up to 199us
usleep(rand_Dc());
}
printf("end camion\n");
return NULL;
}
int rand_D(){
return (rand()%999)+1000;
}
int rand_Dc(){
return (rand()%99)+100;
}
\ No newline at end of file