On Thu, Jun 24, 2010 at 02:13:55AM +0100, Federico G. Schwindt wrote:
> On Wed, Jun 23, 2010 at 05:32:13PM -0700, Matthew Dempsky wrote:
> > On Wed, Jun 23, 2010 at 4:10 PM, Joerg Goltermann <[email protected]> wrote:
> > > I am working on a port and need the POSIX function sem_timedwait. Does 
> > > anyone
> > > have a nice/simple idea how to mimic this function? Is anyone working on 
> > > an
> > > implementation in libpthread?
> > 
> > It looks like it should be simple enough to add.  We already have
> > pthread_cond_timedwait, so sem_timedwait should just be a variant of
> > sem_wait using that instead of pthread_cond_wait.
> > 
> > I'll write one up unless someone with actual libpthread expertise
> > beats me to it. =]
> 
>   i just wrote it but for some reason is not working as expected, which is 
> odd 
> since it's relying on pthread_cond_timedwait. maybe the tests are wrong.
>   being 2am i think i call it a day.

  and the diff, including the manpage bits.
 
  f.-

Index: include/semaphore.h
===================================================================
RCS file: /cvs/src/lib/libpthread/include/semaphore.h,v
retrieving revision 1.3
diff -u -p include/semaphore.h
--- include/semaphore.h 16 Feb 2002 21:27:25 -0000      1.3
+++ include/semaphore.h 24 Jun 2010 01:20:08 -0000
@@ -58,6 +58,7 @@ sem_t  *sem_open(const char *, int, ...);
 int    sem_close(sem_t *);
 int    sem_unlink(const char *);
 int    sem_wait(sem_t *);
+int    sem_timedwait(sem_t *, const struct timespec *);
 int    sem_trywait(sem_t *);
 int    sem_post(sem_t *);
 int    sem_getvalue(sem_t *, int *);
Index: man/Makefile.inc
===================================================================
RCS file: /cvs/src/lib/libpthread/man/Makefile.inc,v
retrieving revision 1.24
diff -u -p man/Makefile.inc
--- man/Makefile.inc    12 Apr 2010 01:54:23 -0000      1.24
+++ man/Makefile.inc    24 Jun 2010 01:20:08 -0000
@@ -105,5 +105,6 @@ MLINKS+=flockfile.3 funlockfile.3 \
        pthread_getconcurrency.3 pthread_setconcurrency.3 \
        sem_open.3 sem_close.3 \
        sem_open.3 sem_unlink.3 \
+       sem_wait.3 sem_timedwait.3 \
        sem_wait.3 sem_trywait.3
 
Index: man/sem_wait.3
===================================================================
RCS file: /cvs/src/lib/libpthread/man/sem_wait.3,v
retrieving revision 1.6
diff -u -p man/sem_wait.3
--- man/sem_wait.3      31 May 2007 19:19:37 -0000      1.6
+++ man/sem_wait.3      24 Jun 2010 01:20:08 -0000
@@ -33,6 +33,7 @@
 .Os
 .Sh NAME
 .Nm sem_wait ,
+.Nm sem_timedwait ,
 .Nm sem_trywait
 .Nd decrement (lock) a semaphore
 .Sh SYNOPSIS
@@ -41,6 +42,10 @@
 .Fn sem_wait "sem_t *sem"
 .Ft int
 .Fn sem_trywait "sem_t *sem"
+.Fd #include <semaphore.h>
+.Fd #include <time.h>
+.Ft int
+.Fn sem_timedwait "sem_t *sem" "const struct timespec *abstime"
 .Sh DESCRIPTION
 The
 .Fn sem_wait
@@ -51,12 +56,19 @@ but blocks if the value of
 is zero, until the value is non-zero and the value can be decremented.
 .Pp
 The
+.Fn sem_timedwait
+function performs the same action, but will not wait beyond
+.Fa abstime
+to decrement (lock) the semaphore before returning.
+.Pp
+The
 .Fn sem_trywait
 function decrements (locks) the semaphore pointed to by
 .Fa sem
 only if the value is non-zero.
 Otherwise, the semaphore is not decremented and
 an error is returned.
+.Pp
 .Sh RETURN VALUES
 .Rv -std sem_wait
 .Sh ERRORS
@@ -68,6 +80,19 @@ will fail if:
 .It Bq Er EINVAL
 .Fa sem
 points to an invalid semaphore.
+.El
+.Pp
+.Fn sem_timedwait
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+.Fa sem
+points to an invalid semaphore or
+.Fa abstime
+is invalid.
+.It Bq Er ETIMEDOUT
+The system time has reached or exceeded the time specified in
+.Fa abstime .
 .El
 .Pp
 Additionally,
Index: uthread/uthread_sem.c
===================================================================
RCS file: /cvs/src/lib/libpthread/uthread/uthread_sem.c,v
retrieving revision 1.3
diff -u -p uthread/uthread_sem.c
--- uthread/uthread_sem.c       20 Jun 2008 02:58:00 -0000      1.3
+++ uthread/uthread_sem.c       24 Jun 2010 01:20:08 -0000
@@ -184,6 +184,36 @@ sem_wait(sem_t *sem)
 }
 
 int
+sem_timedwait(sem_t *sem, const struct timespec *abstime)
+{
+       int     retval = 0;
+
+       _thread_enter_cancellation_point();
+       
+       _SEM_CHECK_VALIDITY(sem);
+
+       pthread_mutex_lock(&(*sem)->lock);
+
+       while ((*sem)->count == 0 && retval == 0) {
+               (*sem)->nwaiters++;
+               retval = pthread_cond_timedwait(&(*sem)->gtzero,
+                   &(*sem)->lock, abstime);
+               (*sem)->nwaiters--;
+       }
+       if (retval != 0) {
+               errno = retval;
+               retval = -1;
+       } else
+               (*sem)->count--;
+
+       pthread_mutex_unlock(&(*sem)->lock);
+
+  RETURN:
+       _thread_leave_cancellation_point();
+       return retval;
+}
+
+int
 sem_trywait(sem_t *sem)
 {
        int     retval;

Reply via email to