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.
This commit is contained in:
Ulrich Drepper 2004-04-18 02:37:56 +00:00
parent f532641db7
commit 1683daeb27
19 changed files with 365 additions and 21 deletions

View File

@ -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

View 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.

View 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. */

View 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
{

View 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));
}

View 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>

View 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

View 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):

View 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)

View 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. */

View 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
{

View 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)));
}

View File

@ -0,0 +1 @@
#include <rt/tst-mqueue8.c>

View 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>

View 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.

View 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)

266
rt/tst-mqueue8.c Normal file
View File

@ -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"

View File

@ -1 +1,4 @@
64bit-predefine = __s390x__
ifeq ($(subdir),rt)
librt-routines += rt-sysdep
endif

View File

@ -0,0 +1 @@
#include <sysdep.S>