sem.c 3.2 KB

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