diff options
Diffstat (limited to 'sysdeps/generic')
-rw-r--r-- | sysdeps/generic/bits/semaphore.h | 43 | ||||
-rw-r--r-- | sysdeps/generic/sem-close.c | 32 | ||||
-rw-r--r-- | sysdeps/generic/sem-destroy.c | 38 | ||||
-rw-r--r-- | sysdeps/generic/sem-getvalue.c | 33 | ||||
-rw-r--r-- | sysdeps/generic/sem-init.c | 46 | ||||
-rw-r--r-- | sysdeps/generic/sem-open.c | 32 | ||||
-rw-r--r-- | sysdeps/generic/sem-post.c | 62 | ||||
-rw-r--r-- | sysdeps/generic/sem-timedwait.c | 92 | ||||
-rw-r--r-- | sysdeps/generic/sem-trywait.c | 42 | ||||
-rw-r--r-- | sysdeps/generic/sem-unlink.c | 32 | ||||
-rw-r--r-- | sysdeps/generic/sem-wait.c | 32 |
11 files changed, 484 insertions, 0 deletions
diff --git a/sysdeps/generic/bits/semaphore.h b/sysdeps/generic/bits/semaphore.h new file mode 100644 index 00000000..b53f47e3 --- /dev/null +++ b/sysdeps/generic/bits/semaphore.h @@ -0,0 +1,43 @@ +/* Semaphore type. Generic version. + Copyright (C) 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _BITS_SEMAPHORE_H +#define _BITS_SEMAPHORE_H 1 + +#ifndef _SEMAPHORE_H +#error Never include <bits/semaphore.h> directly. +#endif + +#include <pthread.h> + +/* User visible part of a semaphore. */ +struct __semaphore + { + __pthread_spinlock_t __lock; + struct __pthread *__queue; + int __pshared; + int __value; + void *__data; + }; + +/* Initializer for a semaphore. */ +#define __SEMAPHORE_INITIALIZER(pshared, value) \ + { __SPIN_LOCK_INITIALIZER, NULL, (pshared), (value), NULL } + +#endif /* bits/mutex.h */ diff --git a/sysdeps/generic/sem-close.c b/sysdeps/generic/sem-close.c new file mode 100644 index 00000000..b82946bf --- /dev/null +++ b/sysdeps/generic/sem-close.c @@ -0,0 +1,32 @@ +/* Close a named semaphore. Generic version. + Copyright (C) 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <semaphore.h> +#include <errno.h> + +#include <pt-internal.h> + +int +__sem_close (sem_t *sem) +{ + errno = EOPNOTSUPP; + return -1; +} + +weak_alias (__sem_close, sem_close); diff --git a/sysdeps/generic/sem-destroy.c b/sysdeps/generic/sem-destroy.c new file mode 100644 index 00000000..693b06dd --- /dev/null +++ b/sysdeps/generic/sem-destroy.c @@ -0,0 +1,38 @@ +/* Destroy a semaphore. Generic version. + Copyright (C) 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <semaphore.h> +#include <errno.h> + +#include <pt-internal.h> + +int +__sem_destroy (sem_t *sem) +{ + if (sem->__queue) + /* There are threads waiting on *SEM. */ + { + errno = EBUSY; + return -1; + } + + return 0; +} + +weak_alias (__sem_destroy, sem_destroy); diff --git a/sysdeps/generic/sem-getvalue.c b/sysdeps/generic/sem-getvalue.c new file mode 100644 index 00000000..cb0439c4 --- /dev/null +++ b/sysdeps/generic/sem-getvalue.c @@ -0,0 +1,33 @@ +/* Get the value of a semaphore. Generic version. + Copyright (C) 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <semaphore.h> +#include <pt-internal.h> + +int +__sem_getvalue (sem_t *restrict sem, int *restrict value) +{ + __pthread_spin_lock (&sem->__lock); + *value = sem->__value; + __pthread_spin_unlock (&sem->__lock); + + return 0; +} + +weak_alias (__sem_getvalue, sem_getvalue); diff --git a/sysdeps/generic/sem-init.c b/sysdeps/generic/sem-init.c new file mode 100644 index 00000000..f516ec98 --- /dev/null +++ b/sysdeps/generic/sem-init.c @@ -0,0 +1,46 @@ +/* Initialize a semaphore. Generic version. + Copyright (C) 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <semaphore.h> +#include <errno.h> + +#include <pt-internal.h> + +int +__sem_init (sem_t *sem, int pshared, unsigned value) +{ + if (pshared != 0) + { + errno = EOPNOTSUPP; + return -1; + } + +#ifdef SEM_VALUE_MAX + if (value > SEM_VALUE_MAX) + { + errno = EINVAL; + return -1; + } +#endif + + *sem = (sem_t) __SEMAPHORE_INITIALIZER (pshared, value); + return 0; +} + +weak_alias (__sem_init, sem_init); diff --git a/sysdeps/generic/sem-open.c b/sysdeps/generic/sem-open.c new file mode 100644 index 00000000..426cbdb8 --- /dev/null +++ b/sysdeps/generic/sem-open.c @@ -0,0 +1,32 @@ +/* Open a named semaphore. Generic version. + Copyright (C) 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <semaphore.h> +#include <errno.h> + +#include <pt-internal.h> + +sem_t * +__sem_open (const char *name, int open_flags, ...) +{ + errno = EOPNOTSUPP; + return SEM_FAILED; +} + +weak_alias (__sem_open, sem_open); diff --git a/sysdeps/generic/sem-post.c b/sysdeps/generic/sem-post.c new file mode 100644 index 00000000..c283784e --- /dev/null +++ b/sysdeps/generic/sem-post.c @@ -0,0 +1,62 @@ +/* Post a semaphore. Generic version. + Copyright (C) 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <semaphore.h> +#include <assert.h> + +#include <pt-internal.h> + +int +__sem_post (sem_t *sem) +{ + struct __pthread *wakeup; + + __pthread_spin_lock (&sem->__lock); + if (sem->__value > 0) + /* Do a quick up. */ + { + assert (! sem->__queue); + sem->__value ++; + __pthread_spin_unlock (&sem->__lock); + return 0; + } + + if (! sem->__queue) + /* No one waiting. */ + { + sem->__value = 1; + __pthread_spin_unlock (&sem->__lock); + return 0; + } + + /* Wake someone up. */ + + /* First dequeue someone. */ + wakeup = sem->__queue; + __pthread_dequeue (wakeup); + + /* Then drop the lock and transfer control. */ + __pthread_spin_unlock (&sem->__lock); + + __pthread_wakeup (wakeup); + + return 0; +} + +weak_alias (__sem_post, sem_post); diff --git a/sysdeps/generic/sem-timedwait.c b/sysdeps/generic/sem-timedwait.c new file mode 100644 index 00000000..f3d280b7 --- /dev/null +++ b/sysdeps/generic/sem-timedwait.c @@ -0,0 +1,92 @@ +/* Wait on a semaphore with a timeout. Generic version. + Copyright (C) 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <semaphore.h> +#include <error.h> +#include <errno.h> +#include <assert.h> + +#include <pt-internal.h> + +int +__sem_timedwait_internal (sem_t *restrict sem, + const struct timespec *restrict timeout) +{ + struct __pthread *self; + + __pthread_spin_lock (&sem->__lock); + if (sem->__value > 0) + /* Successful down. */ + { + sem->__value --; + __pthread_spin_unlock (&sem->__lock); + return 0; + } + + /* Add ourselves to the queue. */ + self = _pthread_self (); + + __pthread_enqueue (&sem->__queue, self); + __pthread_spin_unlock (&sem->__lock); + + /* Block the thread. */ + if (timeout) + { + error_t err; + + if (timeout->tv_nsec < 0 || timeout->tv_nsec >= 1000000000) + { + errno = EINVAL; + return -1; + } + + err = __pthread_timedblock (self, timeout); + if (err) + /* We timed out. We may need to disconnect ourself from the + waiter queue. + + FIXME: What do we do if we get a wakeup message before we + disconnect ourself? It may remain until the next time we + block. */ + { + assert (err == ETIMEDOUT); + + __pthread_spin_lock (&sem->__lock); + if (self->prevp) + __pthread_dequeue (self); + __pthread_spin_unlock (&sem->__lock); + + errno = err; + return -1; + } + } + else + __pthread_block (self); + + return 0; +} + +int +__sem_timedwait (sem_t *restrict sem, + const struct timespec *restrict timeout) +{ + return __sem_timedwait_internal (sem, timeout); +} + +weak_alias (__sem_timedwait, sem_timedwait); diff --git a/sysdeps/generic/sem-trywait.c b/sysdeps/generic/sem-trywait.c new file mode 100644 index 00000000..e47d5595 --- /dev/null +++ b/sysdeps/generic/sem-trywait.c @@ -0,0 +1,42 @@ +/* Lock a semaphore if it does not require blocking. Generic version. + Copyright (C) 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <semaphore.h> +#include <errno.h> + +#include <pt-internal.h> + +int +__sem_trywait (sem_t *sem) +{ + __pthread_spin_lock (&sem->__lock); + if (sem->__value > 0) + /* Successful down. */ + { + sem->__value --; + __pthread_spin_unlock (&sem->__lock); + return 0; + } + __pthread_spin_unlock (&sem->__lock); + + errno = EAGAIN; + return -1; +} + +weak_alias (__sem_trywait, sem_trywait); diff --git a/sysdeps/generic/sem-unlink.c b/sysdeps/generic/sem-unlink.c new file mode 100644 index 00000000..95b63ed8 --- /dev/null +++ b/sysdeps/generic/sem-unlink.c @@ -0,0 +1,32 @@ +/* Unlink a named semaphore. Generic version. + Copyright (C) 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <semaphore.h> +#include <errno.h> + +#include <pt-internal.h> + +int +__sem_unlink (const char *name) +{ + errno = EOPNOTSUPP; + return -1; +} + +weak_alias (__sem_unlink, sem_unlink); diff --git a/sysdeps/generic/sem-wait.c b/sysdeps/generic/sem-wait.c new file mode 100644 index 00000000..46c7baf4 --- /dev/null +++ b/sysdeps/generic/sem-wait.c @@ -0,0 +1,32 @@ +/* Wait on a semaphore. Generic version. + Copyright (C) 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <semaphore.h> +#include <pt-internal.h> + +extern int __sem_timedwait_internal (sem_t *restrict sem, + const struct timespec *restrict timeout); + +int +__sem_wait (sem_t *sem) +{ + return __sem_timedwait_internal (sem, 0); +} + +weak_alias (__sem_wait, sem_wait); |