1#include "port.h" 2#include "semaphore.h" 3#include <unistd.h> 4#include <stdlib.h> 5 6Semaphore::Semaphore(int semKey, int numSems, int val) 7 : m_semid(0) 8 , m_semflg(IPC_CREAT | 0666) 9 , m_semopen(false) 10 , m_semKey(semKey) 11 , m_numSems(numSems) 12{ 13 m_arg.val = (0); 14 if(val) 15 { 16 if(create(val)) 17 exit(1); 18 } 19} 20 21int Semaphore::clear_sem() 22{ 23 int semid; 24 // have num-sems set to 1 so that we remove regardless of how many 25 // semaphores were present. 26 if((semid = semget(m_semKey, 1, 0666)) == -1) 27 { 28 perror("Can't get semaphore ID"); 29 return 1; 30 } 31 if(semctl(semid, 0, IPC_RMID, m_arg) == -1) 32 { 33 perror("Can't get remove semaphore"); 34 return 1; 35 } 36 printf("Semaphore removed.\n"); 37 return 0; 38} 39 40int Semaphore::create(int count) 41{ 42 if((m_semid = semget(m_semKey, m_numSems, m_semflg)) == -1) 43 { 44 perror("Can't get semaphore"); 45 return 1; 46 } 47 m_arg.val = count; 48 int i; 49 for(i = 0; i < m_numSems; ++i) 50 { 51 if(semctl(m_semid, i, SETVAL, m_arg) == -1) 52 { 53 perror("Can't set semaphore value"); 54 return 1; 55 } 56 } 57 m_semopen = true; 58 return 0; 59} 60 61int Semaphore::get_semid() 62{ 63 int semflg = 0666; 64 if ((m_semid = semget(m_semKey, m_numSems, semflg)) == -1) 65 { 66 perror("Can't get semaphore ID"); 67 return 1; 68 } 69 m_semopen = true; 70 return 0; 71} 72 73int Semaphore::decrement_and_wait(int nr_sem) 74{ 75 if(!m_semopen) 76 return 0; 77 struct sembuf sops; 78 sops.sem_num = nr_sem; 79 sops.sem_op = -1; 80 sops.sem_flg = IPC_NOWAIT; 81 if(semop(m_semid, &sops, 1) == -1) 82 { 83 perror("semop: semop failed.\n"); 84 return 1; 85 } 86 sops.sem_num = nr_sem; 87 sops.sem_op = 0; 88 sops.sem_flg = SEM_UNDO; 89 if(semop(m_semid, &sops, 1) == -1) 90 { 91 perror("semop: semop failed.\n"); 92 return 1; 93 } 94 return 0; 95} 96 97int Semaphore::get_mutex() 98{ 99 if(!m_semopen) 100 return 0; 101 struct sembuf sops; 102 sops.sem_num = 0; 103 sops.sem_op = -1; 104 sops.sem_flg = SEM_UNDO; 105 if(semop(m_semid, &sops, 1) == -1) 106 { 107 perror("semop: semop failed.\n"); 108 return 1; 109 } 110 return 0; 111} 112 113int Semaphore::put_mutex() 114{ 115 if(!m_semopen) 116 return 0; 117 struct sembuf sops; 118 sops.sem_num = 0; 119 sops.sem_op = 1; 120 sops.sem_flg = IPC_NOWAIT; 121 if(semop(m_semid, &sops, 1) == -1) 122 { 123 perror("semop: semop failed.\n"); 124 return 1; 125 } 126 return 0; 127} 128