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