Update.
authorUlrich Drepper <drepper@redhat.com>
Sun, 18 Apr 2004 02:37:56 +0000 (02:37 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sun, 18 Apr 2004 02:37:56 +0000 (02:37 +0000)
2004-04-17  Jakub Jelinek  <jakub@redhat.com>

* rt/Makefile (tests): Add tst-mqueue8.
* rt/tst-mqueue8.c: New test.

* sysdeps/unix/sysv/linux/s390/Makefile (librt-routines): Add
rt-sysdep.
* sysdeps/unix/sysv/linux/s390/rt-sysdep.S: New file.

19 files changed:
ChangeLog
linuxthreads/ChangeLog
linuxthreads/sysdeps/pthread/timer_create.c
linuxthreads/sysdeps/pthread/timer_gettime.c
linuxthreads/sysdeps/pthread/timer_routines.c
linuxthreads/sysdeps/unix/sysv/linux/mq_notify.c
linuxthreads/sysdeps/x86_64/tls.h
nptl/ChangeLog
nptl/sysdeps/pthread/Makefile
nptl/sysdeps/pthread/timer_create.c
nptl/sysdeps/pthread/timer_gettime.c
nptl/sysdeps/pthread/timer_routines.c
nptl/sysdeps/pthread/tst-mqueue8x.c [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/mq_notify.c
nptl/tst-cancel4.c
rt/Makefile
rt/tst-mqueue8.c [new file with mode: 0644]
sysdeps/unix/sysv/linux/s390/Makefile
sysdeps/unix/sysv/linux/s390/rt-sysdep.S [new file with mode: 0644]

index 8d4fd0a866e888d50388f4fd80df4ac323903cc8..f3d032bdfa38abbefb72ab2acdc2ae9c0b669b7c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2004-04-17  Jakub Jelinek  <jakub@redhat.com>
+
+       * rt/Makefile (tests): Add tst-mqueue8.
+       * rt/tst-mqueue8.c: New test.
+
+       * sysdeps/unix/sysv/linux/s390/Makefile (librt-routines): Add
+       rt-sysdep.
+       * sysdeps/unix/sysv/linux/s390/rt-sysdep.S: New file.
+
 2004-03-26  H.J. Lu  <hongjiu.lu@intel.com>
 
        * sysdeps/unix/sysv/linux/wordsize-64/fxstat.c (__fxstat): Don't
index 48a873c47bc8ebced7004db829e28cf8fe9ce783..45d38b383b5e30bc7caaac5d353d52cae500e3d8 100644 (file)
@@ -1,3 +1,18 @@
+2004-04-17  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/x86_64/tls.h [!__ASSEMBLER__]: Include tcb-offsets.h.
+
+       * sysdeps/pthread/timer_gettime.c (timer_gettime): For expired timer
+       return it_value { 0, 0 }.
+       * sysdeps/pthread/timer_create.c (timer_create): Handle SIGEV_NONE
+       like SIGEV_SIGNAL.
+       * sysdeps/pthread/timer_routines.c (thread_expire_timer): Remove
+       assertion for SIGEV_NONE.
+       (thread_attr_compare): Compare all attributes, not just a partial
+       subset.
+
+       * sysdeps/unix/sysv/linux/mq_notify.c: Include stdlib.h.
+
 2004-04-17  Ulrich Drepper  <drepper@redhat.com>
 
        * semaphore.h (SEM_VALUE_MAX): Just use a plain number.
index d63cda06873928627982a501cca544da0a446f1f..3fde4c74c9aa31c101c23d470e61715d128fe2eb 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Kaz Kylheku <kaz@ashi.footprints.net>.
 
@@ -91,9 +91,6 @@ timer_create (clock_id, evp, timerid)
   switch (__builtin_expect (newtimer->event.sigev_notify, SIGEV_SIGNAL))
     {
     case SIGEV_NONE:
-      /* This is a strange choice!  */
-      break;
-
     case SIGEV_SIGNAL:
       /* We have a global thread for delivering timed signals.
         If it is not running, try to start it up.  */
index 99a080311c7cd0d312fe81565596821af4d4b8aa..723a61632fa4b8b199f5bc6de036d7c49212efcc 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Kaz Kylheku <kaz@ashi.footprints.net>.
 
@@ -54,7 +54,13 @@ timer_gettime (timerid, value)
       if (armed)
        {
          clock_gettime (clock, &now);
-         timespec_sub (&value->it_value, &expiry, &now);
+         if (timespec_compare (&now, &expiry) < 0)
+           timespec_sub (&value->it_value, &expiry, &now);
+         else
+           {
+             value->it_value.tv_sec = 0;
+             value->it_value.tv_nsec = 0;
+           }
        }
       else
        {
index 36c26b2a012befcd22ba0539c9d09e72903fed7d..6e3797d0b578d776db7616d79ac1c4c5194729b9 100644 (file)
@@ -1,5 +1,5 @@
 /* Helper code for POSIX timer implementation on LinuxThreads.
-   Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Kaz Kylheku <kaz@ashi.footprints.net>.
 
@@ -318,7 +318,6 @@ thread_expire_timer (struct thread_node *self, struct timer_node *timer)
   switch (__builtin_expect (timer->event.sigev_notify, SIGEV_SIGNAL))
     {
     case SIGEV_NONE:
-      assert (! "timer_create should never have created such a timer");
       break;
 
     case SIGEV_SIGNAL:
@@ -517,10 +516,15 @@ thread_attr_compare (const pthread_attr_t *left, const pthread_attr_t *right)
 {
   return (left->__detachstate == right->__detachstate
          && left->__schedpolicy == right->__schedpolicy
+         && left->__guardsize == right->__guardsize
          && (left->__schedparam.sched_priority
              == right->__schedparam.sched_priority)
          && left->__inheritsched == right->__inheritsched
-         && left->__scope == right->__scope);
+         && left->__scope == right->__scope
+         && left->__stacksize == right->__stacksize
+         && left->__stackaddr_set == right->__stackaddr_set
+         && (left->__stackaddr_set
+             || left->__stackaddr == right->__stackaddr));
 }
 
 
index 2714fadb9dbed0f1e1b00432c911c094c9fcab75..e9c2b6e79a45da5798a39c58c65c28dddb7885fc 100644 (file)
@@ -23,6 +23,7 @@
 #include <mqueue.h>
 #include <pthread.h>
 #include <signal.h>
+#include <stdlib.h>
 #include <string.h>
 #include <sysdep.h>
 #include <unistd.h>
index 124c849dc8d0ae51180d70c5986c311c5307f71a..63feebdb2c64bdc593c2e686958d87e810683be8 100644 (file)
@@ -41,6 +41,9 @@ typedef struct
   void *self;          /* Pointer to the thread descriptor.  */
   int multiple_threads;
 } tcbhead_t;
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
 #endif
 
 
index f0b074d79464f63fa2765ff2b49847ad0c0081f9..ff3498fb74b94f4a26178b139ad6251c8754da66 100644 (file)
@@ -1,3 +1,24 @@
+2004-04-17  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/pthread/Makefile (tests): Add tst-mqueue8x
+       in rt subdir.
+       (CFLAGS-tst-mqueue8x.c): Add -fexceptions.
+       * sysdeps/pthread/tst-mqueue8x.c: New test.
+       * tst-cancel4.c: Update comment about message queues.
+
+       * sysdeps/pthread/timer_gettime.c (timer_gettime): For expired timer
+       return it_value { 0, 0 }.
+       * sysdeps/pthread/timer_create.c (timer_create): Handle SIGEV_NONE
+       like SIGEV_SIGNAL.
+       * sysdeps/pthread/timer_routines.c (thread_expire_timer): Remove
+       assertion for SIGEV_NONE.
+       (thread_attr_compare): Compare all attributes, not just a partial
+       subset.
+
+2004-04-17  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/mq_notify.c: Include stdlib.h.
+
 2004-04-17  Ulrich Drepper  <drepper@redhat.com>
 
        * sysdeps/unix/sysv/linux/alpha/bits/semaphore.h (SEM_VALUE_MAX):
index aac94065eb24f6f76ffbf2b094a205b8b51b07f0..05854beecd94382b6775ac52a945279f7ed8b1d0 100644 (file)
@@ -40,6 +40,11 @@ $(objpfx)tst-timer: $(objpfx)librt.so $(shared-thread-library)
 else
 $(objpfx)tst-timer: $(objpfx)librt.a $(static-thread-library)
 endif
+
+ifeq ($(have-forced-unwind),yes)
+tests += tst-mqueue8x
+CFLAGS-tst-mqueue8x.c += -fexceptions
+endif
 endif
 
 ifeq ($(subdir),posix)
index 16aa8100b427d3d377ba9fcb5566f8d22b726e3c..b74fafda62403de1933246ffd0ae792523c6fdc2 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Kaz Kylheku <kaz@ashi.footprints.net>.
 
@@ -91,9 +91,6 @@ timer_create (clock_id, evp, timerid)
   switch (__builtin_expect (newtimer->event.sigev_notify, SIGEV_SIGNAL))
     {
     case SIGEV_NONE:
-      /* This is a strange choice!  */
-      break;
-
     case SIGEV_SIGNAL:
       /* We have a global thread for delivering timed signals.
         If it is not running, try to start it up.  */
index 99a080311c7cd0d312fe81565596821af4d4b8aa..723a61632fa4b8b199f5bc6de036d7c49212efcc 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Kaz Kylheku <kaz@ashi.footprints.net>.
 
@@ -54,7 +54,13 @@ timer_gettime (timerid, value)
       if (armed)
        {
          clock_gettime (clock, &now);
-         timespec_sub (&value->it_value, &expiry, &now);
+         if (timespec_compare (&now, &expiry) < 0)
+           timespec_sub (&value->it_value, &expiry, &now);
+         else
+           {
+             value->it_value.tv_sec = 0;
+             value->it_value.tv_nsec = 0;
+           }
        }
       else
        {
index af6f7412b631d665c28987412777d8d4e444ba41..3ee8fef17bc839587fa046feb56f99c0ec5f30bf 100644 (file)
@@ -1,5 +1,5 @@
 /* Helper code for POSIX timer implementation on NPTL.
-   Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Kaz Kylheku <kaz@ashi.footprints.net>.
 
@@ -319,7 +319,6 @@ thread_expire_timer (struct thread_node *self, struct timer_node *timer)
   switch (__builtin_expect (timer->event.sigev_notify, SIGEV_SIGNAL))
     {
     case SIGEV_NONE:
-      assert (! "timer_create should never have created such a timer");
       break;
 
     case SIGEV_SIGNAL:
@@ -522,7 +521,15 @@ thread_attr_compare (const pthread_attr_t *left, const pthread_attr_t *right)
   return (ileft->flags == iright->flags
          && ileft->schedpolicy == iright->schedpolicy
          && (ileft->schedparam.sched_priority
-             == iright->schedparam.sched_priority));
+             == iright->schedparam.sched_priority)
+         && ileft->guardsize == iright->guardsize
+         && ileft->stackaddr == iright->stackaddr
+         && ileft->stacksize == iright->stacksize
+         && ((ileft->cpuset == NULL && iright->cpuset == NULL)
+             || (ileft->cpuset != NULL && iright->cpuset != NULL
+                 && ileft->cpusetsize == iright->cpusetsize
+                 && memcmp (ileft->cpuset, iright->cpuset,
+                            ileft->cpusetsize) == 0)));
 }
 
 
diff --git a/nptl/sysdeps/pthread/tst-mqueue8x.c b/nptl/sysdeps/pthread/tst-mqueue8x.c
new file mode 100644 (file)
index 0000000..ca28039
--- /dev/null
@@ -0,0 +1 @@
+#include <rt/tst-mqueue8.c>
index 2714fadb9dbed0f1e1b00432c911c094c9fcab75..e9c2b6e79a45da5798a39c58c65c28dddb7885fc 100644 (file)
@@ -23,6 +23,7 @@
 #include <mqueue.h>
 #include <pthread.h>
 #include <signal.h>
+#include <stdlib.h>
 #include <string.h>
 #include <sysdep.h>
 #include <unistd.h>
index 8af6d422ce58678090c14ffaf0cc8ca6c1e48a39..87000fa6a4451ae3bc21506356baf4046f3b7543 100644 (file)
@@ -57,8 +57,8 @@
 
    sem_wait() and sem_timedwait() are checked in tst-cancel1[2345] tests.
 
-   POSIX message queues aren't implemented yet.  This affects
-     mq_receive()    mq_send()   mq_timedreceive()  mq_timedsend()
+   mq_send(), mq_timedsend(), mq_receive() and mq_timedreceive() are checked
+   in tst-mqueue8{,x} tests.
 
    aio_suspend() is tested in tst-cancel17.
 
index 24801c4d181271d1004ca2c83f19627a359e66b2..a5ce82fbca6e6f5f6bdb05be43858fc543b869ce 100644 (file)
@@ -44,7 +44,8 @@ librt-routines = $(aio-routines) \
 tests := tst-shm tst-clock tst-clock_nanosleep tst-timer tst-timer2 \
         tst-aio tst-aio64 tst-aio2 tst-aio3 tst-aio4 tst-aio5 tst-aio6 \
         tst-aio7 tst-mqueue1 tst-mqueue2 tst-mqueue3 tst-mqueue4 \
-        tst-mqueue5 tst-mqueue6 tst-mqueue7 tst-timer3 tst-timer4
+        tst-mqueue5 tst-mqueue6 tst-mqueue7 tst-mqueue8 \
+        tst-timer3 tst-timer4
 
 extra-libs := librt
 extra-libs-others := $(extra-libs)
diff --git a/rt/tst-mqueue8.c b/rt/tst-mqueue8.c
new file mode 100644 (file)
index 0000000..7e902aa
--- /dev/null
@@ -0,0 +1,266 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <mqueue.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#if _POSIX_THREADS
+# include <pthread.h>
+
+static pthread_barrier_t b;
+
+/* Cleanup handling test.  */
+static int cl_called;
+
+static void
+cl (void *arg)
+{
+  ++cl_called;
+}
+
+#define TF_MQ_RECEIVE          0L
+#define TF_MQ_TIMEDRECEIVE     1L
+#define TF_MQ_SEND             2L
+#define TF_MQ_TIMEDSEND                3L
+
+static const char *names[]
+  = { "mq_receive", "mq_timedreceive", "mq_send", "mq_timedsend" };
+
+static mqd_t q;
+static struct timespec never;
+
+static void *
+tf (void *arg)
+{
+  int r = pthread_barrier_wait (&b);
+  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      puts ("tf: barrier_wait failed");
+      exit (1);
+    }
+
+  pthread_cleanup_push (cl, NULL);
+
+  char c = ' ';
+
+  switch ((long) arg)
+    {
+    case TF_MQ_SEND:
+      TEMP_FAILURE_RETRY (mq_send (q, &c, 1, 1));
+      break;
+    case TF_MQ_TIMEDSEND:
+      TEMP_FAILURE_RETRY (mq_timedsend (q, &c, 1, 1, &never));
+      break;
+    case TF_MQ_RECEIVE:
+      TEMP_FAILURE_RETRY (mq_receive (q, &c, 1, NULL));
+      break;
+    case TF_MQ_TIMEDRECEIVE:
+      TEMP_FAILURE_RETRY (mq_timedreceive (q, &c, 1, NULL, &never));
+      break;
+    }
+
+  pthread_cleanup_pop (0);
+
+  printf ("tf: %s returned\n", names[(long) arg]);
+
+  exit (1);
+}
+
+#define TEST_FUNCTION do_test ()
+static int
+do_test (void)
+{
+  char name[sizeof "/tst-mqueue8-" + sizeof (pid_t) * 3];
+  snprintf (name, sizeof (name), "/tst-mqueue8-%u", getpid ());
+
+  struct mq_attr attr = { .mq_maxmsg = 1, .mq_msgsize = 1 };
+  q = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
+
+  if (q == (mqd_t) -1)
+    {
+      printf ("mq_open failed with: %m\n");
+      return 0;
+    }
+
+  if (mq_unlink (name) != 0)
+    {
+      printf ("mq_unlink failed with: %m\n");
+      return 1;
+    }
+
+  if (pthread_barrier_init (&b, NULL, 2) != 0)
+    {
+      puts ("barrier_init failed");
+      return 1;
+    }
+
+  if (clock_gettime (CLOCK_REALTIME, &never) == 0)
+    never.tv_sec += 100;
+  else
+    {
+      never.tv_sec = time (NULL) + 100;
+      never.tv_nsec = 0;
+    }
+
+  int result = 0;
+  for (long l = TF_MQ_RECEIVE; l <= TF_MQ_TIMEDSEND; ++l)
+    {
+      cl_called = 0;
+
+      pthread_t th;
+      if (pthread_create (&th, NULL, tf, (void *) l) != 0)
+       {
+         printf ("1st %s create failed\n", names[l]);
+         result = 1;
+         continue;
+       }
+
+      int r = pthread_barrier_wait (&b);
+      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+       {
+         puts ("barrier_wait failed");
+         result = 1;
+         continue;
+       }
+
+      struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
+      while (nanosleep (&ts, &ts) != 0)
+       continue;
+
+      printf ("going to cancel %s in-time\n", names[l]);
+      if (pthread_cancel (th) != 0)
+       {
+         printf ("1st cancel of %s failed\n", names[l]);
+         result = 1;
+         continue;
+       }
+
+      void *status;
+      if (pthread_join (th, &status) != 0)
+       {
+         printf ("1st join of %s failed\n", names[l]);
+         result = 1;
+         continue;
+       }
+      if (status != PTHREAD_CANCELED)
+       {
+         printf ("1st %s thread not canceled\n", names[l]);
+         result = 1;
+         continue;
+       }
+
+      if (cl_called == 0)
+       {
+         printf ("%s cleanup handler not called\n", names[l]);
+         result = 1;
+         continue;
+       }
+      if (cl_called > 1)
+       {
+         printf ("%s cleanup handler called more than once\n", names[l]);
+         result = 1;
+         continue;
+       }
+
+      printf ("in-time %s cancellation succeeded\n", names[l]);
+
+      cl_called = 0;
+
+      if (pthread_create (&th, NULL, tf, (void *) l) != 0)
+       {
+         printf ("2nd %s create failed\n", names[l]);
+         result = 1;
+         continue;
+       }
+
+      printf ("going to cancel %s early\n", names[l]);
+      if (pthread_cancel (th) != 0)
+       {
+         printf ("2nd cancel of %s failed\n", names[l]);
+         result = 1;
+         continue;
+       }
+
+      r = pthread_barrier_wait (&b);
+      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+       {
+         puts ("barrier_wait failed");
+         result = 1;
+         continue;
+       }
+
+      if (pthread_join (th, &status) != 0)
+       {
+         printf ("2nd join of %s failed\n", names[l]);
+         result = 1;
+         continue;
+       }
+      if (status != PTHREAD_CANCELED)
+       {
+         printf ("2nd %s thread not canceled\n", names[l]);
+         result = 1;
+         continue;
+       }
+
+      if (cl_called == 0)
+       {
+         printf ("%s cleanup handler not called\n", names[l]);
+         result = 1;
+         continue;
+       }
+      if (cl_called > 1)
+       {
+         printf ("%s cleanup handler called more than once\n", names[l]);
+         result = 1;
+         continue;
+       }
+
+      printf ("early %s cancellation succeeded\n", names[l]);
+
+      if (l == TF_MQ_TIMEDRECEIVE)
+       {
+         /* mq_receive and mq_timedreceive are tested on empty mq.
+            For mq_send and mq_timedsend we need to make it full.
+            If this fails, there is no point in doing further testing.  */
+         char c = ' ';
+         if (mq_send (q, &c, 1, 1) != 0)
+           {
+             printf ("mq_send failed: %m\n");
+             result = 1;
+             break;
+           }
+       }
+    }
+
+  if (mq_close (q) != 0)
+    {
+      printf ("mq_close failed: %m\n");
+      result = 1;
+    }
+
+  return result;
+}
+#else
+# define TEST_FUNCTION 0
+#endif
+
+#include "../test-skeleton.c"
index 7a83286d0a21b06b09992e05e2e5c495f982fba5..8d8df743ac8a75c3c387df3178fa1054a5837bb8 100644 (file)
@@ -1 +1,4 @@
 64bit-predefine = __s390x__
+ifeq ($(subdir),rt)
+librt-routines += rt-sysdep
+endif
diff --git a/sysdeps/unix/sysv/linux/s390/rt-sysdep.S b/sysdeps/unix/sysv/linux/s390/rt-sysdep.S
new file mode 100644 (file)
index 0000000..f966bf1
--- /dev/null
@@ -0,0 +1 @@
+#include <sysdep.S>