summaryrefslogtreecommitdiff
path: root/util/lock/csem.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/lock/csem.c')
-rw-r--r--util/lock/csem.c275
1 files changed, 0 insertions, 275 deletions
diff --git a/util/lock/csem.c b/util/lock/csem.c
deleted file mode 100644
index 2ad3d5d873..0000000000
--- a/util/lock/csem.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright 2003 Sun Microsystems, Inc.
- * Copyright 2010 Google, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Developer's note: This was open sourced by Sun Microsystems, which got it
- * via Cobalt Networks. It has been fairly extensively modified since then.
- */
-
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE 1
-#endif
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/sem.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <errno.h>
-#include <sched.h>
-
-#include "csem.h"
-
-#if (defined(__BIONIC__) || defined(__GNU_LIBRARY__)) && !defined(_SEM_SEMUN_UNDEFINED)
-/* union semun is defined by including <sys/sem.h> */
-#else
-/* according to X/OPEN we have to define it ourselves */
-union semun {
- int val; /* value for SETVAL */
- struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
- unsigned short int *array; /* array for GETALL, SETALL */
- struct seminfo *__buf; /* buffer for IPC_INFO */
-};
-#endif
-
-/*
- * On some platforms semctl(SETVAL) sets sem_otime, on other platforms it
- * does not. Figure out what this platform does.
- *
- * Returns 0 if semctl(SETVAL) does not set sem_otime
- * Returns 1 if semctl(SETVAL) does set sem_otime
- * Returns -1 on error
- */
-static int does_semctl_set_otime(void)
-{
- int sem_id;
- int ret;
-
- /* create a test semaphore */
- sem_id = semget(IPC_PRIVATE, 1, S_IRUSR|S_IWUSR);
- if (sem_id < 0)
- return -1;
-
- /* set the value */
- if (csem_setval(sem_id, 1) < 0) {
- csem_destroy(sem_id);
- return -1;
- }
-
- /* read sem_otime */
- ret = (csem_get_otime(sem_id) > 0) ? 1 : 0;
-
- /* clean up */
- csem_destroy(sem_id);
-
- return ret;
-}
-
-int csem_create(key_t key, unsigned val)
-{
- static int need_otime_hack = -1;
- int sem_id;
-
- /* see if we need to trigger a semop to set sem_otime */
- if (need_otime_hack < 0) {
- int ret = does_semctl_set_otime();
- if (ret < 0)
- return -1;
-
- need_otime_hack = !ret;
- }
-
- /* create it or fail */
- sem_id = semget(key, 1, IPC_CREAT|IPC_EXCL | S_IRUSR|S_IWUSR);
- if (sem_id < 0)
- return -1;
-
- /* initalize the value */
- if (need_otime_hack)
- val++;
-
- if (csem_setval(sem_id, val) < 0) {
- csem_destroy(sem_id);
- return -1;
- }
-
- if (need_otime_hack) {
- /* force sem_otime to change */
- csem_down(sem_id);
- }
-
- return sem_id;
-}
-
-/* how many times to loop, waiting for sem_otime */
-#define MAX_OTIME_LOOPS 1000
-
-int csem_get(key_t key)
-{
- int sem_id;
- int i;
-
- /* CSEM_PRIVATE needs to go through csem_create() to get an
- * initial value */
- if (key == CSEM_PRIVATE) {
- errno = EINVAL;
- return -1;
- }
-
- /* get the (assumed existing) semaphore */
- sem_id = semget(key, 1, S_IRUSR|S_IWUSR);
- if (sem_id < 0)
- return -1;
-
- /* loop until sem_otime != 0, which means it has been initialized */
- for (i = 0; i < MAX_OTIME_LOOPS; i++) {
- time_t otime = csem_get_otime(sem_id);
- if (otime < 0) {
- /* error */
- return -1;
- }
- if (otime > 0) {
- /* success */
- return sem_id;
- }
- /* retry */
- sched_yield();
- }
-
- /* fell through - error */
- return -1;
-}
-
-int csem_get_or_create(key_t key, unsigned val)
-{
- int sem_id;
-
- /* try to create the semaphore */
- sem_id = csem_create(key, val);
- if (sem_id >= 0 || errno != EEXIST) {
- /* it either succeeded or got an error */
- return sem_id;
- }
-
- /* it must exist already - get it */
- sem_id = csem_get(key);
- if (sem_id < 0)
- return -1;
-
- return sem_id;
-}
-
-int csem_destroy(int sem_id)
-{
- return semctl(sem_id, 0, IPC_RMID);
-}
-
-int csem_getval(int sem_id)
-{
- return semctl(sem_id, 0, GETVAL);
-}
-
-int csem_setval(int sem_id, unsigned val)
-{
- union semun arg;
- arg.val = val;
- if (semctl(sem_id, 0, SETVAL, arg) < 0)
- return -1;
-
- return 0;
-}
-
-static int csem_up_undoflag(int sem_id, int undoflag)
-{
- struct sembuf sops;
- sops.sem_num = 0;
- sops.sem_op = 1;
- sops.sem_flg = undoflag;
- return semop(sem_id, &sops, 1);
-}
-
-int csem_up(int sem_id)
-{
- return csem_up_undoflag(sem_id, 0);
-}
-
-int csem_up_undo(int sem_id)
-{
- return csem_up_undoflag(sem_id, SEM_UNDO);
-}
-
-static int csem_down_undoflag(int sem_id, int undoflag)
-{
- struct sembuf sops;
- sops.sem_num = 0;
- sops.sem_op = -1;
- sops.sem_flg = undoflag;
- return semop(sem_id, &sops, 1);
-}
-
-int csem_down(int sem_id)
-{
- return csem_down_undoflag(sem_id, 0);
-}
-
-int csem_down_undo(int sem_id)
-{
- return csem_down_undoflag(sem_id, SEM_UNDO);
-}
-
-static int csem_down_timeout_undoflag(int sem_id,
- struct timespec *timeout,
- int undoflag)
-{
- struct sembuf sops;
- sops.sem_num = 0;
- sops.sem_op = -1;
- sops.sem_flg = undoflag;
- return semtimedop(sem_id, &sops, 1, timeout);
-}
-
-int csem_down_timeout(int sem_id, struct timespec *timeout)
-{
- return csem_down_timeout_undoflag(sem_id, timeout, 0);
-}
-
-int csem_down_timeout_undo(int sem_id, struct timespec *timeout)
-{
- return csem_down_timeout_undoflag(sem_id, timeout, SEM_UNDO);
-}
-
-time_t csem_get_otime(int sem_id)
-{
- union semun arg;
- struct semid_ds ds;
- arg.buf = &ds;
- if (semctl(sem_id, 0, IPC_STAT, arg) < 0)
- return -1;
-
- return ds.sem_otime;
-}