sem.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #define _XOPEN_SOURCE
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <sys/stat.h> /* Constante option */
  5. #include <errno.h>
  6. #include "error.h"
  7. #include "sem.h"
  8. /* --- Extern --- */
  9. extern int errno;
  10. /* --- Fonctions privées --- */
  11. /**
  12. * Initialise les semaphores
  13. * @param semaphore* Le tableau de semaphore
  14. * @param int La taille du tableau
  15. * @param int* Valeur à initialiser
  16. * @return boolean Reussite
  17. */
  18. boolean ini_sem(semaphore* sem, int size, int* iniVal) {
  19. /* Initialisation des valeurs */
  20. for(int i = 0; i < size; i++){
  21. if(semctl(sem->id, i, SETVAL, iniVal[i]) == ERR){
  22. addperror("Impossible d'initialiser le tableau de semaphore");
  23. return false;
  24. }
  25. }
  26. /* Retour */
  27. return true;
  28. }
  29. /* --- Fonctions publiques --- */
  30. boolean create_sem(semaphore* sem, int code, int nb, int* iniVal) {
  31. int id;
  32. /* Création du tableau */
  33. key_t key = ftok(IPCKEYPATH, code);
  34. if(key == ERR){
  35. addperror("Impossible de générer la clef");
  36. return false;
  37. }
  38. id = semget(key, nb, S_IRUSR | S_IWUSR | IPC_CREAT | IPC_EXCL);
  39. if (id == ERR) {
  40. /* Si le tableau existe deja */
  41. if (errno == EEXIST) {
  42. adderror("Le tableau de sémaphore existe deja, tentaive de récupération");
  43. return get_sem(sem, code);
  44. }
  45. /* Sinon erreur */
  46. addperror("Impossible de créer le tableau de sémaphore");
  47. return false;
  48. }
  49. /* Paramétrage de la structure */
  50. sem->id = id;
  51. sem->key = key;
  52. sem->nb = nb;
  53. /* Initialise semaphore */
  54. return ini_sem(sem, nb, iniVal);
  55. }
  56. boolean get_sem(semaphore* sem, int code) {
  57. int id;
  58. struct semid_ds sem_buf;
  59. /* Création du tableau */
  60. key_t key = ftok(IPCKEYPATH, code);
  61. if(key == ERR){
  62. addperror("Impossible de générer la clef");
  63. return false;
  64. }
  65. id = semget(key, 0, S_IRUSR | S_IWUSR);
  66. if (id == ERR) {
  67. /* Sinon erreur */
  68. addperror("Impossible de récupèrer le tableau de sémaphore");
  69. return false;
  70. }
  71. /* Récupération du nombre de semaphore */
  72. if (semctl(id, 0, IPC_STAT, &sem_buf) == ERR) {
  73. addperror("Impossible de récupèrer les informations du tableau de sémaphore");
  74. return false;
  75. }
  76. /* Paramétrage de la structure */
  77. sem->id = id;
  78. sem->key = key;
  79. sem->nb = sem_buf.sem_nsems;
  80. /* Retour */
  81. return true;
  82. }
  83. boolean P(semaphore* sem, int num) {
  84. struct sembuf action;
  85. /* Le num valide */
  86. if (num < 0 || num > (sem->nb - 1)) {
  87. adderror("Index tableau semaphore invalide");
  88. return false;
  89. }
  90. /* Parametre sembuf */
  91. action.sem_num = num;
  92. action.sem_op = -1;
  93. /* Puis je */
  94. if (semop(sem->id, &action, 1) == ERR) {
  95. addperror("Impossible d'effectuer P");
  96. return false;
  97. }
  98. return true;
  99. }
  100. boolean V(semaphore* sem, int num) {
  101. struct sembuf action;
  102. /* Le num valide */
  103. if (num < 0 || num > (sem->nb - 1)) {
  104. adderror("Index tableau semaphore invalide");
  105. return false;
  106. }
  107. /* Parametre sembuf */
  108. action.sem_num = num;
  109. action.sem_op = 1;
  110. /* Vas y */
  111. if (semop(sem->id, &action, 1) == ERR) {
  112. addperror("Impossible d'effectuer V");
  113. return false;
  114. }
  115. return true;
  116. }
  117. boolean delete_sem(semaphore* sem) {
  118. /* Suppr */
  119. if (semctl(sem->id, 0, IPC_RMID) == ERR) {
  120. addperror("Impossible de supprimer le tableau de semaphore");
  121. return false;
  122. }
  123. /* Reset struct */
  124. sem->id = 0;
  125. sem->key = 0;
  126. sem->nb = 0;
  127. return true;
  128. }
  129. int get_sem_value(semaphore* sem, int num){
  130. return semctl(sem->id, num, GETVAL);
  131. }