(_SC_IOV_MAX): New definition.
[kopensolaris-gnu/glibc.git] / linuxthreads / oldsemaphore.c
index 5a19a45..82cd637 100644 (file)
@@ -19,6 +19,8 @@
 /* GNU Library General Public License for more details.                 */
 
 /* Semaphores a la POSIX 1003.1b */
+#include <shlib-compat.h>
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
 
 #include <errno.h>
 #include "pthread.h"
@@ -32,12 +34,20 @@ typedef struct {
     int sem_spinlock;
 } old_sem_t;
 
+extern int __old_sem_init (old_sem_t *__sem, int __pshared, unsigned int __value);
+extern int __old_sem_wait (old_sem_t *__sem);
+extern int __old_sem_trywait (old_sem_t *__sem);
+extern int __old_sem_post (old_sem_t *__sem);
+extern int __old_sem_getvalue (old_sem_t *__sem, int *__sval);
+extern int __old_sem_destroy (old_sem_t *__sem);
+
+
 /* Maximum value the semaphore can have.  */
 #define SEM_VALUE_MAX   ((int) ((~0u) >> 1))
 
 static inline int sem_compare_and_swap(old_sem_t *sem, long oldval, long newval)
 {
-    return __pthread_compare_and_swap(&sem->sem_status, oldval, newval, &sem->sem_spinlock);
+    return compare_and_swap(&sem->sem_status, oldval, newval, &sem->sem_spinlock);
 }
 
 /* The state of a semaphore is represented by a long int encoding
@@ -63,18 +73,34 @@ int __old_sem_init(old_sem_t *sem, int pshared, unsigned int value)
        errno = ENOSYS;
        return -1;
     }
-  sem->sem_spinlock = 0;
+  sem->sem_spinlock = LT_SPINLOCK_INIT;
   sem->sem_status = ((long)value << 1) + 1;
   return 0;
 }
 
+/* Function called by pthread_cancel to remove the thread from
+   waiting inside __old_sem_wait. Here we simply unconditionally
+   indicate that the thread is to be woken, by returning 1. */
+
+static int old_sem_extricate_func(void *obj, pthread_descr th)
+{
+    return 1;
+}
+
 int __old_sem_wait(old_sem_t * sem)
 {
     long oldstatus, newstatus;
     volatile pthread_descr self = thread_self();
     pthread_descr * th;
+    pthread_extricate_if extr;
+
+    /* Set up extrication interface */
+    extr.pu_object = 0;
+    extr.pu_extricate_func = old_sem_extricate_func;
 
     while (1) {
+       /* Register extrication interface */
+       __pthread_set_own_extricate_if(self, &extr);
        do {
             oldstatus = sem->sem_status;
             if ((oldstatus & 1) && (oldstatus != 1))
@@ -85,11 +111,15 @@ int __old_sem_wait(old_sem_t * sem)
            }
        }
        while (! sem_compare_and_swap(sem, oldstatus, newstatus));
-       if (newstatus & 1)
+       if (newstatus & 1) {
            /* We got the semaphore. */
+         __pthread_set_own_extricate_if(self, 0);
            return 0;
+       }
        /* Wait for sem_post or cancellation */
-       suspend_with_cancellation(self);
+       suspend(self);
+       __pthread_set_own_extricate_if(self, 0);
+
        /* This is a cancellation point */
        if (self->p_canceled && self->p_cancelstate == PTHREAD_CANCEL_ENABLE) {
            /* Remove ourselves from the waiting list if we're still on it */
@@ -204,12 +234,11 @@ static void sem_restart_list(pthread_descr waiting)
   }
 }
 
-#if defined PIC && DO_VERSIONING
-symbol_version (__old_sem_init, sem_init, GLIBC_2.0);
-symbol_version (__old_sem_wait, sem_wait, GLIBC_2.0);
-symbol_version (__old_sem_trywait, sem_trywait, GLIBC_2.0);
-symbol_version (__old_sem_post, sem_post, GLIBC_2.0);
-symbol_version (__old_sem_getvalue, sem_getvalue, GLIBC_2.0);
-symbol_version (__old_sem_destroy, sem_destroy, GLIBC_2.0);
-#endif
+compat_symbol (libpthread, __old_sem_init, sem_init, GLIBC_2_0);
+compat_symbol (libpthread, __old_sem_wait, sem_wait, GLIBC_2_0);
+compat_symbol (libpthread, __old_sem_trywait, sem_trywait, GLIBC_2_0);
+compat_symbol (libpthread, __old_sem_post, sem_post, GLIBC_2_0);
+compat_symbol (libpthread, __old_sem_getvalue, sem_getvalue, GLIBC_2_0);
+compat_symbol (libpthread, __old_sem_destroy, sem_destroy, GLIBC_2_0);
 
+#endif