cours_prog_systeme/TP/TP2/shared_mem.c
2021-08-22 13:28:10 +02:00

195 lines
No EOL
4.1 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#define KEY 160
#define NB_ITERATION 100000
/*
* TP2 Partie 3 Communication par mémoire partagée
* On observe une alternance correct et derterministe.
* Le débit calculé est cohérent
*/
void utilisation() {
printf("Usage : ./a.out [c] [s]\n");
exit(-1);
}
int main(int argc, char *argv[]) {
int server = -1;
struct timeval begin, end;
// Variables SHM
int key_shm = KEY;
int *shm = NULL;
int shmid = 0;
// Variables IPC
int key = KEY;
int init_s = 0;
int init_c = 1;
char recv[1];
struct sembuf op;
int sem_s, sem_c;
/* Traitement des arguments */
if (argc != 2) {
utilisation();
}
if (*argv[1] == 's') {
server = 1;
sem_s = semget((key_t)key, 1, 666 | IPC_CREAT);
sem_c = semget((key_t)key+1, 1, 666 | IPC_CREAT);
} else if (*argv[1] == 'c') {
sem_s = semget((key_t)key, 0, 0);
sem_c = semget((key_t)key+1, 0, 0);
server = 0;
} else {
utilisation();
}
/* Création du sémaphore */
if (sem_s < 0 || sem_c < 0) {
printf("Erreur création sémaphore.\n");
exit(-1);
}
/* Initialisation du sémaphore */
if (server) {
if (semctl(sem_s, 0, SETVAL, init_s) == -1 || semctl(sem_c, 0, SETVAL, init_c) == -1) {
printf("Erreur initialisation sémaphore.\n");
exit(-1);
}
}
op.sem_num = 0;
op.sem_flg = 0;
/* Création de la SHM */
if (!(shmid = shmget((key_t)key_shm, 4, 0666 | IPC_CREAT))) {
printf("Erreur création SHM.\n");
exit(-1);
}
/* Attachement de la shm */
if (!(shm = (int *)shmat(shmid, 0, 0))) {
printf("Erreur attache SHM.\n");
exit(-1);
}
////////SERVER////////
if (server) {
printf("Mode serveur.\n");
for (int i = 0; i < (NB_ITERATION/2); ++i) {
op.sem_op = -1;
//printf("Serveur en attente...\n");
if (semop(sem_s, &op, 1)) {
printf("Erreur attente.\n");
exit(-1);
}
//printf("On incrémente le shm...");
(*shm)++;
//printf("Fait.\n");
//sleep(1);
op.sem_op = 1;
//printf("Le serveur rend la main.\n");
if (semop(sem_c, &op, 1)) {
printf("Erreur op.\n");
exit(-1);
}
}
}
////////CLIENT////////
else {
printf("Mode client.\n");
printf("Lancement du chronometre.\n");
gettimeofday(&begin, NULL);
for (int i = 0; i < (NB_ITERATION/2); ++i) {
op.sem_op = -1;
//printf("Client en attente...\n");
if (semop(sem_c, &op, 1)) {
printf("Erreur attente.\n");
exit(-1);
}
//printf("On incrémente le shm...");
(*shm)++;
//printf("Fait.\n");
//sleep(1);
//printf("Le client rend la main.\n");
op.sem_op = 1;
if (semop(sem_s, &op, 1)) {
printf("Erreur op.\n");
exit(-1);
}
}
gettimeofday(&end, NULL);
op.sem_op = -1;
if (semop(sem_c, &op, 1)) {
printf("Erreur attente.\n");
exit(-1);
}
}
printf("Valeur finale SHM : %d\n", *shm);
/* detache la SHM */
if (shmdt(shm)) {
printf("Erreur détachement.\n");
exit(-1);
}
if (!server) {
/* Destruction SHM */
if (shmctl(shmid, IPC_RMID, 0)) {
printf("Erreur destruction SHM.\n");
exit(-1);
}
/* Libération sémaphore */
if (semctl(sem_s, 0, IPC_RMID, 0) || semctl(sem_c, 0, IPC_RMID, 0)) {
printf("Erreur libération sémaphore.\n");
exit(-1);
}
/* Calcul débit*/
int delta =
((end.tv_sec - begin.tv_sec) * 1000000L + end.tv_usec) - begin.tv_usec;
int debit =
(NB_ITERATION * 2 * sizeof(int) * 8) / (delta); // (delta est déjà en us)
printf("Débit calculé : %d Mb/s\n", debit);
}
printf("Fin.\n");
return 0;
}
/*
if (server) {
printf("Affectation de la valeur par le serveur.\n");
*shm = 10;
sleep(10);
printf("Nouvelle valeur lue par le serveur : %d\n", *shm);
}
else {
printf("Valeur lue par le client : %d\n", *shm);
*shm = 28;
printf("Valeur modifiée par le client : %d\n", *shm);
}
*/