My Project
Loading...
Searching...
No Matches
semaphore.c
Go to the documentation of this file.
1#include "kernel/mod2.h"
2
3#ifdef HAVE_SIMPLEIPC
4#include <semaphore.h>
5#include <fcntl.h>
6#include <sys/types.h>
7#include <sys/stat.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <sys/types.h>
11#include <unistd.h>
12
13# include "simpleipc.h"
14
15#include "Singular/cntrlc.h"
16#include "reporter/si_signals.h"
17
18
19
20// Not yet implemented: SYSV IPC Semaphores
21// They are more difficult to clean up after a process crash
22// but are supported more widely.
23
26
27/* return 1 on success,
28 * 0 if already initialized,
29 * -1 for errors
30 */
31int sipc_semaphore_init(int id, int count)
32{
33 char buf[100];
34 sipc_sem_t *sem;
35 if ((id<0) || (id >= SIPC_MAX_SEMAPHORES))
36 return -1;
37 // Already initialized?
38 if (semaphore[id])
39 return 0;
40 // to make it completely safe, we should generate a name
41 // from /dev/urandom.
42#if USE_SEM_INIT
43 // TODO: This should really use mapped memory so that processes
44 // can keep using the semaphore after fork + exec.
45 sem = malloc(sizeof(sem_t));
46 if (!sem)
47 return -1;
48 if (sem_init(sem, 1, count) < 0)
49 {
50 free(sem);
51 return -1;
52 }
53#else
54#if PORTABLE_SEMAPHORES
55#ifndef MAP_ANONYMOUS
56#define MAP_ANONYMOUS MAP_ANON
57#endif
58 sem = mmap(NULL, getpagesize(),
59 PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_SHARED, -1, 0);
60 if (sem == MAP_FAILED)
61 return -1;
62 sem->count = count;
63 sprintf(buf, "/%d:sem%d:g", getpid(), id);
64 sem_unlink(buf);
65 sem->guard = sem_open(buf, O_CREAT, 0600, count);
66 sem_unlink(buf);
67 sprintf(buf, "/%d:sem%d:s", getpid(), id);
68 sem_unlink(buf);
69 sem->sig = sem_open(buf, O_CREAT, 0600, count);
70 sem_unlink(buf);
71#else
72 sprintf(buf, "/%d:sem%d", getpid(), id);
73 sem_unlink(buf);
74 sem = sem_open(buf, O_CREAT, 0600, count);
75#endif
76#endif
77#if !PORTABLE_SEMAPHORES
78 if (sem == SEM_FAILED || !sem)
79 return -1;
80#endif
81 semaphore[id] = sem;
82#if !USE_SEM_INIT
83 sem_unlink(buf);
84#endif
85 return 1;
86}
87
89{
90 if ((id<0) || (id >= SIPC_MAX_SEMAPHORES)) return -1;
91 return semaphore[id] != NULL;
92}
93
95{
96 if ((id<0) || (id >= SIPC_MAX_SEMAPHORES) || (semaphore[id]==NULL)) return -1;
98#if PORTABLE_SEMAPHORES
99 si_sem_wait(semaphore[id]->sig);
100 si_sem_wait(semaphore[id]->guard);
101 semaphore[id]->count--;
102 sem_post(semaphore[id]->guard);
103#else
104 si_sem_wait(semaphore[id]);
105#endif
106 sem_acquired[id]++;
109 return 1;
110}
111
113{
114 if ((id<0) || (id >= SIPC_MAX_SEMAPHORES) || (semaphore[id]==NULL)) return -1;
116#if PORTABLE_SEMAPHORES
117 int trywait = si_sem_trywait(semaphore[id]->sig);
118#else
119 int trywait = si_sem_trywait(semaphore[id]);
120#endif
121 if (!trywait)
122 {
123#if PORTABLE_SEMAPHORES
124 si_sem_wait(semaphore[id]->guard);
125 semaphore[id]->count--;
126 sem_post(semaphore[id]->guard);
127#endif
128 sem_acquired[id]++;
129 }
132 return !trywait;
133}
134
136{
137 if ((id<0) || (id >= SIPC_MAX_SEMAPHORES) || (semaphore[id]==NULL)) return -1;
139#if PORTABLE_SEMAPHORES
140 sem_wait(semaphore[id]->guard);
141 semaphore[id]->count++;
142 sem_post(semaphore[id]->sig);
143 sem_post(semaphore[id]->guard);
144#else
145 sem_post(semaphore[id]);
146#endif
147 sem_acquired[id]--;
150 return 1;
151}
152
154{
155 int val;
156 if ((id<0) || (id >= SIPC_MAX_SEMAPHORES) || (semaphore[id]==NULL)) return -1;
157#if PORTABLE_SEMAPHORES
158 sem_wait(semaphore[id]->guard);
159 val = semaphore[id]->count;
160 sem_post(semaphore[id]->guard);
161#else
162 sem_getvalue(semaphore[id], &val);
163#endif
164 return val;
165}
166
167int simpleipc_cmd(char *cmd, int id, int v)
168{
169 if (strcmp(cmd,"init")==0)
170 return sipc_semaphore_init(id,v);
171 else if (strcmp(cmd,"exists")==0)
172 return sipc_semaphore_exists(id);
173 else if (strcmp(cmd,"acquire")==0)
174 return sipc_semaphore_acquire(id);
175 else if (strcmp(cmd,"try_acquire")==0)
177 else if (strcmp(cmd,"release")==0)
178 return sipc_semaphore_release(id);
179 else if (strcmp(cmd,"get_value")==0)
180 return sipc_semaphore_get_value(id);
181 else printf("unknown\n");
182 return -2;
183}
184#endif
VAR volatile BOOLEAN do_shutdown
Definition: cntrlc.cc:74
VAR volatile int defer_shutdown
Definition: cntrlc.cc:75
const Variable & v
< [in] a sqrfree bivariate poly
Definition: facBivar.h:39
#define VAR
Definition: globaldefs.h:5
void m2_end(int i)
Definition: misc_ip.cc:1097
#define free
Definition: omAllocFunc.c:14
#define malloc
Definition: omAllocFunc.c:12
#define NULL
Definition: omList.c:12
int sipc_semaphore_get_value(int id)
Definition: semaphore.c:153
int sipc_semaphore_acquire(int id)
Definition: semaphore.c:94
VAR sipc_sem_t * semaphore[SIPC_MAX_SEMAPHORES]
Definition: semaphore.c:24
VAR int sem_acquired[SIPC_MAX_SEMAPHORES]
Definition: semaphore.c:25
int sipc_semaphore_release(int id)
Definition: semaphore.c:135
int simpleipc_cmd(char *cmd, int id, int v)
Definition: semaphore.c:167
int sipc_semaphore_exists(int id)
Definition: semaphore.c:88
int sipc_semaphore_try_acquire(int id)
Definition: semaphore.c:112
int sipc_semaphore_init(int id, int count)
Definition: semaphore.c:31
int status int void size_t count
Definition: si_signals.h:59
int status int void * buf
Definition: si_signals.h:59
#define SIPC_MAX_SEMAPHORES
Definition: simpleipc.h:10
sem_t sipc_sem_t
Definition: simpleipc.h:27