2 * Copyright 2012 GRNET S.A. All rights reserved.
4 * Redistribution and use in source and binary forms, with or
5 * without modification, are permitted provided that the following
8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following
11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials
14 * provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
29 * The views and conclusions contained in the software and
30 * documentation are those of the authors and should not be
31 * interpreted as representing official policies, either expressed
32 * or implied, of GRNET S.A.
39 #include <sys/types.h>
42 #include <sys/syscall.h>
48 #include <xseg/xseg.h>
49 #include <xtypes/xobj.h>
50 #include <drivers/xseg_posix.h>
54 static long posix_allocate(const char *name, uint64_t size)
57 fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0770);
59 XSEGLOG("Cannot create shared segment: %s\n",
60 strerror_r(errno, errbuf, ERRSIZE));
64 r = lseek(fd, size -1, SEEK_SET);
67 XSEGLOG("Cannot seek into segment file: %s\n",
68 strerror_r(errno, errbuf, ERRSIZE));
73 r = write(fd, errbuf, 1);
76 XSEGLOG("Failed to set segment size: %s\n",
77 strerror_r(errno, errbuf, ERRSIZE));
85 static long posix_deallocate(const char *name)
87 return shm_unlink(name);
90 static void *posix_map(const char *name, uint64_t size, struct xseg *seg)
96 // XSEGLOG("struct xseg * is not NULL. Ignoring...\n");
98 fd = shm_open(name, O_RDWR, 0000);
100 XSEGLOG("Failed to open '%s' for mapping: %s\n",
101 name, strerror_r(errno, errbuf, ERRSIZE));
105 xseg = mmap ( XSEG_BASE_AS_PTR,
107 PROT_READ | PROT_WRITE,
108 MAP_SHARED | MAP_FIXED /* | MAP_LOCKED */,
111 if (xseg == MAP_FAILED) {
112 XSEGLOG("Could not map segment: %s\n",
113 strerror_r(errno, errbuf, ERRSIZE));
121 static void posix_unmap(void *ptr, uint64_t size)
123 struct xseg *xseg = ptr;
124 (void)munmap(xseg, xseg->segment_size);
128 static void handler(int signum)
130 static unsigned long counter;
131 printf("%lu: signal %d: this shouldn't have happened.\n", counter, signum);
135 static sigset_t savedset, set;
138 static int posix_local_signal_init(struct xseg *xseg, xport portno)
142 h = signal(SIGIO, handler);
147 sigaddset(&set, SIGIO);
149 r = sigprocmask(SIG_BLOCK, &set, &savedset);
153 pid = syscall(SYS_gettid);
157 static void posix_local_signal_quit(struct xseg *xseg, xport portno)
160 signal(SIGIO, SIG_DFL);
161 sigprocmask(SIG_SETMASK, &savedset, NULL);
164 static int posix_remote_signal_init(void)
169 static void posix_remote_signal_quit(void)
174 static int posix_prepare_wait(struct xseg *xseg, uint32_t portno)
176 struct xseg_port *port = xseg_get_port(xseg, portno);
179 struct posix_signal_desc *psd = xseg_get_signal_desc(xseg, port);
186 static int posix_cancel_wait(struct xseg *xseg, uint32_t portno)
188 struct xseg_port *port = xseg_get_port(xseg, portno);
191 struct posix_signal_desc *psd = xseg_get_signal_desc(xseg, port);
198 static int posix_wait_signal(struct xseg *xseg, void *sd, uint32_t usec_timeout)
204 ts.tv_sec = usec_timeout / 1000000;
205 ts.tv_nsec = 1000 * (usec_timeout - ts.tv_sec * 1000000);
207 /* FIXME: Now that posix signaling is fixed, we could get rid of the timeout
208 * and use a NULL timespec linux-specific)
210 r = sigtimedwait(&set, &siginfo, &ts);
214 return siginfo.si_signo;
217 static int posix_signal(struct xseg *xseg, uint32_t portno)
219 struct xseg_port *port = xseg_get_port(xseg, portno);
222 struct posix_signal_desc *psd = xseg_get_signal_desc(xseg, port);
225 pid_t cue = (pid_t)psd->waitcue;
230 /* FIXME: Make calls to xseg_signal() check for errors */
231 return syscall(SYS_tkill, cue, SIGIO);
234 static void *posix_malloc(uint64_t size)
236 return malloc((size_t)size);
239 static void *posix_realloc(void *mem, uint64_t size)
241 return realloc(mem, (size_t)size);
244 static void posix_mfree(void *mem)
250 int posix_init_signal_desc(struct xseg *xseg, void *sd)
252 struct posix_signal_desc *psd = sd;
259 void posix_quit_signal_desc(struct xseg *xseg, void *sd)
264 void * posix_alloc_data(struct xseg *xseg)
266 struct xobject_h *sd_h = xseg_get_objh(xseg, MAGIC_POSIX_SD,
267 sizeof(struct posix_signal_desc));
271 void posix_free_data(struct xseg *xseg, void *data)
274 xseg_put_objh(xseg, (struct xobject_h *)data);
277 void *posix_alloc_signal_desc(struct xseg *xseg, void *data)
279 struct xobject_h *sd_h = (struct xobject_h *) data;
282 struct posix_signal_desc *psd = xobj_get_obj(sd_h, X_ALLOC);
290 void posix_free_signal_desc(struct xseg *xseg, void *data, void *sd)
292 struct xobject_h *sd_h = (struct xobject_h *) data;
296 xobj_put_obj(sd_h, sd);
300 static struct xseg_type xseg_posix = {
301 /* xseg_operations */
303 .mfree = posix_mfree,
304 .allocate = posix_allocate,
305 .deallocate = posix_deallocate,
307 .unmap = posix_unmap,
313 static struct xseg_peer xseg_peer_posix = {
314 /* xseg_peer_operations */
316 .init_signal_desc = posix_init_signal_desc,
317 .quit_signal_desc = posix_quit_signal_desc,
318 .alloc_data = posix_alloc_data,
319 .free_data = posix_free_data,
320 .alloc_signal_desc = posix_alloc_signal_desc,
321 .free_signal_desc = posix_free_signal_desc,
322 .local_signal_init = posix_local_signal_init,
323 .local_signal_quit = posix_local_signal_quit,
324 .remote_signal_init = posix_remote_signal_init,
325 .remote_signal_quit = posix_remote_signal_quit,
326 .prepare_wait = posix_prepare_wait,
327 .cancel_wait = posix_cancel_wait,
328 .wait_signal = posix_wait_signal,
329 .signal = posix_signal,
330 .malloc = posix_malloc,
331 .realloc = posix_realloc,
332 .mfree = posix_mfree,
338 void xseg_posix_init(void)
340 xseg_register_type(&xseg_posix);
341 xseg_register_peer(&xseg_peer_posix);