This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi! This patch makes IA-64 port work again, with the exception of expected math failures and tst-cancel5 make check passes. linuxthreads/sysdeps/ia64/tls.h is really just a small part, I had no time to make full TLS working ATM on IA-64. I've removed SPARC bits from the patch set, because I hit a linker bug and thus will have to redo part of those changes. 2002-12-21 Jakub Jelinek <jakub@redhat.com> * sysdeps/unix/sysv/linux/ia64/sysdep.h (INLINE_SYSCALL, INTERNAL_SYSCALL, INTERNAL_SYSCALL_ERROR_P, INTERNAL_SYSCALL_ERROR): Define. Patch by Richard Henderson and Jes Sorensen. (PSEUDO): Remove unnecessary ;;. * elf/rtld.c (dl_main): Initialize TLS even if no PT_TLS segments are found unless TLS_INIT_TP_EXPENSIVE. Use NONTLS_INIT_TP. * sysdeps/generic/libc-tls.c (__libc_setup_tls): Use NONTLS_INIT_TP if not initializing thread pointer. [!USE_TLS && NONTLS_INIT_TP] (__pthread_initialize_minimal): New. * sysdeps/generic/libc-start.c (__pthread_initialize_minimal): Don't make it weak also if NONTLS_INIT_TP. * sysdeps/unix/common/pause.c: Handle cancellation. linuxthreads/ * libc_pthread_init.c: Include stdlib.h. * sysdeps/i386/tls.h (tcbhead_t): Add multiple_threads member. (TLS_INIT_TP_EXPENSIVE): Define. * sysdeps/pthread/bits/libc-lock.h (__libc_maybe_call, __libc_maybe_call2): In _LIBC check SHARED define. * sysdeps/ia64/tls.h: New file. * sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h: New file. * sysdeps/unix/sysv/linux/ia64/Makefile: New file. * sysdeps/x86_64/tls.h (TLS_INIT_TP_EXPENSIVE): Define. * Makefile (tests): Add tst-cancel[1-6]. (tests-reverse): Add tst-cancel5. Link libc.so before libpthread.so for tests-reverse. * tst-cancel1.c: New file. * tst-cancel2.c: New file. * tst-cancel3.c: New file. * tst-cancel4.c: New file. * tst-cancel5.c: New file. * tst-cancel6.c: New file. nptl/ * Makefile (tests-reverse): Use $(objpfx)../libc.so instead of $(common-objpfx)libc.so. * tst-cancel4.c (tf_write, tf_writev): Increase buf sizes so that it is bigger than pipe buffer size even on arches with bigger page size. (tf_usleep): Cast usleep argument to useconds_t to avoid warnings. --- libc/elf/rtld.c.jj 2002-12-20 13:34:41.000000000 +0100 +++ libc/elf/rtld.c 2002-12-20 16:02:39.000000000 +0100 @@ -1157,7 +1157,7 @@ of this helper program; chances are you an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever used. Trying to do it lazily is too hairy to try when there could be multiple threads (from a non-TLS-using libpthread). */ - if (GL(dl_tls_max_dtv_idx) > 0) + if (GL(dl_tls_max_dtv_idx) > 0 || !TLS_INIT_TP_EXPENSIVE) { struct link_map *l; size_t nelem; @@ -1565,8 +1565,12 @@ cannot allocate TLS data structures for we need it in the memory handling later. */ GL(dl_initial_searchlist) = *GL(dl_main_searchlist); +#ifndef NONTLS_INIT_TP +# define NONTLS_INIT_TP do { } while (0) +#endif + #ifdef USE_TLS - if (GL(dl_tls_max_dtv_idx) > 0 || USE___THREAD) + if (GL(dl_tls_max_dtv_idx) > 0 || USE___THREAD || !TLS_INIT_TP_EXPENSIVE) { /* Now that we have completed relocation, the initializer data for the TLS blocks has its final values and we can copy them @@ -1579,7 +1583,9 @@ cannot allocate TLS data structures for if (__builtin_expect (lossage != NULL, 0)) _dl_fatal_printf ("cannot set up thread-local storage: %s\n", lossage); } + else #endif + NONTLS_INIT_TP; { /* Initialize _r_debug. */ --- libc/linuxthreads/libc_pthread_init.c.jj 2002-12-18 02:15:55.000000000 +0100 +++ libc/linuxthreads/libc_pthread_init.c 2002-12-20 17:23:42.000000000 +0100 @@ -17,9 +17,10 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <locale.h> +#include <stdlib.h> #include <string.h> #include <tls.h> -#include <locale.h> #include "internals.h" #include <sysdep-cancel.h> --- libc/linuxthreads/sysdeps/i386/tls.h.jj 2002-12-10 15:08:36.000000000 +0100 +++ libc/linuxthreads/sysdeps/i386/tls.h 2002-12-20 16:00:18.000000000 +0100 @@ -39,6 +39,7 @@ typedef struct thread descriptor used by libpthread. */ dtv_t *dtv; void *self; /* Pointer to the thread descriptor. */ + int multiple_threads; } tcbhead_t; #endif @@ -192,6 +193,10 @@ TLS_DO_MODIFY_LDT_KERNEL_CHECK( TLS_SETUP_GS_SEGMENT (_descr, secondcall); \ }) +/* Indicate that dynamic linker shouldn't try to initialize TLS even + when no PT_TLS segments are found in the program and libraries + it is linked against. */ +# define TLS_INIT_TP_EXPENSIVE 1 /* Return the address of the dtv for the current thread. */ # define THREAD_DTV() \ --- libc/linuxthreads/sysdeps/pthread/bits/libc-lock.h.jj 2002-12-20 13:35:37.000000000 +0100 +++ libc/linuxthreads/sysdeps/pthread/bits/libc-lock.h 2002-12-20 17:33:13.000000000 +0100 @@ -97,7 +97,7 @@ typedef pthread_key_t __libc_key_t; #if defined _LIBC && defined IS_IN_libpthread # define __libc_maybe_call(FUNC, ARGS, ELSE) FUNC ARGS #else -# ifdef __PIC__ +# if defined __PIC__ || (defined _LIBC && defined SHARED) # define __libc_maybe_call(FUNC, ARGS, ELSE) \ (__extension__ ({ __typeof (FUNC) *_fn = (FUNC); \ _fn != NULL ? (*_fn) ARGS : ELSE; })) @@ -106,7 +106,7 @@ typedef pthread_key_t __libc_key_t; (FUNC != NULL ? FUNC ARGS : ELSE) # endif #endif -#if defined _LIBC && !defined NOT_IN_libc && defined __PIC__ +#if defined _LIBC && !defined NOT_IN_libc && defined SHARED # define __libc_maybe_call2(FUNC, ARGS, ELSE) \ ({__libc_pthread_functions.ptr_##FUNC != NULL \ ? __libc_pthread_functions.ptr_##FUNC ARGS : ELSE; }) --- libc/linuxthreads/sysdeps/ia64/tls.h.jj 2002-12-20 14:01:54.000000000 +0100 +++ libc/linuxthreads/sysdeps/ia64/tls.h 2002-12-20 20:39:50.000000000 +0100 @@ -0,0 +1,64 @@ +/* Definitions for thread-local data handling. linuxthreads/IA-64 version. + Copyright (C) 2002 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 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. */ + +#ifndef _TLS_H +#define _TLS_H + +#ifndef __ASSEMBLER__ + +# include <pt-machine.h> +# include <stddef.h> + +/* Type for the dtv. */ +typedef union dtv +{ + size_t counter; + void *pointer; +} dtv_t; + + +/* FIXME: Only temporary. When TLS is supported on IA-64, + pthread_descr struct needs to be immediately below r13 and + at r13 a struct { dtv_t *dtv; void *private; }. */ +typedef struct +{ + void *tcb; /* Pointer to the TCB. Not necessary the + thread descriptor used by libpthread. */ + dtv_t *dtv; + void *self; /* Pointer to the thread descriptor. */ + int multiple_threads; +} tcbhead_t; +#endif /* __ASSEMBLER__ */ + +#undef USE_TLS + +#if USE_TLS + +#else + +#define NONTLS_INIT_TP \ + do { \ + static const tcbhead_t nontls_init_tp \ + = { .multiple_threads = NULL }; \ + __thread_self = (__typeof (__thread_self)) &nontls_init_tp; \ + } while (0) + +#endif /* USE_TLS */ + +#endif /* tls.h */ --- libc/linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h.jj 2002-12-20 14:00:36.000000000 +0100 +++ libc/linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h 2002-12-20 22:18:54.000000000 +0100 @@ -0,0 +1,107 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jakub@redhat.com>, 2002. + + 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 <sysdep.h> +#include <tls.h> +#ifndef ASSEMBLER +# include <linuxthreads/internals.h> +#endif + +#define MULTIPLE_THREADS_OFFSET 24 + +#if !defined NOT_IN_libc || defined IS_IN_libpthread + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args) \ +.text; \ +ENTRY (name) \ + adds r14 = MULTIPLE_THREADS_OFFSET, r13;; \ + ld4 r14 = [r14]; \ + mov r15 = SYS_ify(syscall_name);; \ + cmp4.ne p6, p7 = 0, r14; \ +(p6) br.cond.spnt .Lpseudo_cancel;; \ + break __BREAK_SYSCALL;; \ + cmp.eq p6,p0=-1,r10; \ +(p6) br.cond.spnt.few __syscall_error; \ + ret;; \ +.Lpseudo_cancel: \ + .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(args); \ + alloc loc0 = ar.pfs, args, 5, args, 0; \ + mov loc1 = rp;; \ + CENABLE;; \ + mov loc2 = r8; \ + COPY_ARGS_##args \ + mov r15 = SYS_ify(syscall_name); \ + break __BREAK_SYSCALL;; \ + mov loc3 = r8; \ + mov loc4 = r10; \ + mov out0 = loc2; \ + CDISABLE;; \ + cmp.eq p6,p0=-1,loc4; \ +(p6) br.cond.spnt.few __syscall_error_##args; \ + mov r8 = loc3; \ + mov rp = loc1; \ + mov ar.pfs = loc0; \ +.section .gnu.linkonce.t.__syscall_error_##args, "ax"; \ +.global __syscall_error_##args; \ +.hidden __syscall_error_##args; \ +__syscall_error_##args: \ + mov loc4 = r1;; \ + br.call.sptk.many b0 = __errno_location;; \ + st4 [r8] = loc3; \ + mov r1 = loc4; \ + mov rp = loc1; \ + mov r8 = -1; \ + mov ar.pfs = loc0; \ + ret; \ +.previous; \ +.Lpseudo_end: + +# ifdef IS_IN_libpthread +# define CENABLE br.call.sptk.many b0 = __pthread_enable_asynccancel +# define CDISABLE br.call.sptk.many b0 = __pthread_disable_asynccancel +# else +# define CENABLE br.call.sptk.many b0 = __libc_enable_asynccancel +# define CDISABLE br.call.sptk.many b0 = __libc_disable_asynccancel +# endif + +#define COPY_ARGS_0 /* Nothing */ +#define COPY_ARGS_1 COPY_ARGS_0 mov out0 = in0; +#define COPY_ARGS_2 COPY_ARGS_1 mov out1 = in1; +#define COPY_ARGS_3 COPY_ARGS_2 mov out2 = in2; +#define COPY_ARGS_4 COPY_ARGS_3 mov out3 = in3; +#define COPY_ARGS_5 COPY_ARGS_4 mov out4 = in4; +#define COPY_ARGS_6 COPY_ARGS_5 mov out5 = in5; +#define COPY_ARGS_7 COPY_ARGS_6 mov out6 = in6; + +# ifndef ASSEMBLER +# define SINGLE_THREAD_P \ + __builtin_expect (THREAD_GETMEM (THREAD_SELF, \ + p_header.data.multiple_threads) == 0, 1) +# else +# define SINGLE_THREAD_P \ + adds r14 = MULTIPLE_THREADS_OFFSET, r13 ;; ld4 r14 = [r14] ;; cmp4.ne p6, p7 = 0, r14 ;; +# endif + +#elif !defined ASSEMBLER + +/* This code should never be used but we define it anyhow. */ +# define SINGLE_THREAD_P (1) + +#endif --- libc/linuxthreads/sysdeps/unix/sysv/linux/ia64/Makefile.jj 2002-12-20 19:07:20.000000000 +0100 +++ libc/linuxthreads/sysdeps/unix/sysv/linux/ia64/Makefile 2002-12-20 19:07:14.000000000 +0100 @@ -0,0 +1,3 @@ +ifeq ($(subdir),linuxthreads) +libpthread-routines += ptw-sysdep ptw-sigblock ptw-sigprocmask +endif --- libc/linuxthreads/sysdeps/x86_64/tls.h.jj 2002-12-10 15:08:39.000000000 +0100 +++ libc/linuxthreads/sysdeps/x86_64/tls.h 2002-12-20 16:00:54.000000000 +0100 @@ -109,6 +109,11 @@ typedef struct _result ? "cannot set %fs base address for thread-local storage" : 0; \ }) +/* Indicate that dynamic linker shouldn't try to initialize TLS even + when no PT_TLS segments are found in the program and libraries + it is linked against. */ +# define TLS_INIT_TP_EXPENSIVE 1 + /* Return the address of the dtv for the current thread. */ # define THREAD_DTV() \ ({ struct _pthread_descr_struct *__descr; \ --- libc/linuxthreads/Makefile.jj 2002-12-20 13:35:29.000000000 +0100 +++ libc/linuxthreads/Makefile 2002-12-20 22:02:23.000000000 +0100 @@ -72,8 +72,12 @@ endif librt-tests = ex10 ex11 tests = ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 $(librt-tests) ex12 ex13 joinrace \ tststack $(tests-nodelete-$(have-z-nodelete)) ecmutex ex14 ex15 ex16 \ - ex17 ex18 tst-cancel tst-context bug-sleep + ex17 ex18 tst-cancel tst-context bug-sleep \ + tst-cancel1 tst-cancel2 tst-cancel3 tst-cancel4 tst-cancel5 \ + tst-cancel6 test-srcs = tst-signal +# These tests are linked with libc before libpthread +tests-reverse += tst-cancel5 ifeq ($(build-static),yes) tests += tststatic tst-static-locale @@ -147,8 +151,12 @@ $(objpfx)libpthread.so: $(libc-link.so) # Make sure we link with the thread library. ifeq ($(build-shared),yes) $(addprefix $(objpfx), \ - $(filter-out $(tests-static) unload, \ + $(filter-out $(tests-static) $(tests-reverse) unload, \ $(tests) $(test-srcs))): $(objpfx)libpthread.so +# $(objpfx)../libc.so is used instead of $(common-objpfx)libc.so, +# since otherwise libpthread.so comes before libc.so when linking. +$(addprefix $(objpfx), $(tests-reverse)): \ + $(objpfx)../libc.so $(objpfx)libpthread.so $(addprefix $(objpfx),$(librt-tests)): $(common-objpfx)rt/librt.so $(objpfx)unload: $(common-objpfx)dlfcn/libdl.so $(objpfx)unload.out: $(objpfx)libpthread.so --- libc/linuxthreads/tst-cancel1.c.jj 2002-12-20 22:03:13.000000000 +0100 +++ libc/linuxthreads/tst-cancel1.c 2002-11-26 23:49:41.000000000 +0100 @@ -0,0 +1,150 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +static pthread_mutex_t m1 = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t m2 = PTHREAD_MUTEX_INITIALIZER; + +static int cntr; + + +static void +cleanup (void *arg) +{ + if (arg != (void *) 42l) + cntr = 42; + else + cntr = 1; +} + + +static void * +tf (void *arg) +{ + int err; + + pthread_cleanup_push (cleanup, (void *) 42l); + + err = pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + if (err != 0) + { + printf ("setcanceltype failed: %s\n", strerror (err)); + exit (1); + } + + err = pthread_mutex_unlock (&m2); + if (err != 0) + { + printf ("child: mutex_unlock failed: %s\n", strerror (err)); + exit (1); + } + + err = pthread_mutex_lock (&m1); + if (err != 0) + { + printf ("child: 1st mutex_lock failed: %s\n", strerror (err)); + exit (1); + } + + /* We should never come here. */ + + pthread_cleanup_pop (0); + + return NULL; +} + + +static int +do_test (void) +{ + int err; + pthread_t th; + int result = 0; + void *retval; + + /* Get the mutexes. */ + err = pthread_mutex_lock (&m1); + if (err != 0) + { + printf ("parent: 1st mutex_lock failed: %s\n", strerror (err)); + return 1; + } + err = pthread_mutex_lock (&m2); + if (err != 0) + { + printf ("parent: 2nd mutex_lock failed: %s\n", strerror (err)); + return 1; + } + + err = pthread_create (&th, NULL, tf, NULL); + if (err != 0) + { + printf ("create failed: %s\n", strerror (err)); + return 1; + } + + err = pthread_mutex_lock (&m2); + if (err != 0) + { + printf ("parent: 3rd mutex_lock failed: %s\n", strerror (err)); + return 1; + } + + err = pthread_cancel (th); + if (err != 0) + { + printf ("cancel failed: %s\n", strerror (err)); + return 1; + } + + err = pthread_join (th, &retval); + if (err != 0) + { + printf ("join failed: %s\n", strerror (err)); + return 1; + } + + if (retval != PTHREAD_CANCELED) + { + printf ("wrong return value: %p\n", retval); + result = 1; + } + + if (cntr == 42) + { + puts ("cleanup handler called with wrong argument"); + result = 1; + } + else if (cntr != 1) + { + puts ("cleanup handling not called"); + result = 1; + } + + return result; +} + + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" --- libc/linuxthreads/tst-cancel2.c.jj 2002-12-20 22:03:13.000000000 +0100 +++ libc/linuxthreads/tst-cancel2.c 2002-11-26 23:49:53.000000000 +0100 @@ -0,0 +1,100 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 <pthread.h> +#include <signal.h> +#include <stdio.h> +#include <unistd.h> + + +static int fd[2]; + + +static void * +tf (void *arg) +{ + /* The buffer size must be larger than the pipe size so that the + write blocks. */ + char buf[100000]; + + if (write (fd[1], buf, sizeof (buf)) == sizeof (buf)) + { + puts ("write succeeded"); + return (void *) 1l; + } + + return (void *) 42l; +} + + +static int +do_test (void) +{ + pthread_t th; + void *r; + struct sigaction sa; + + sa.sa_handler = SIG_IGN; + sigemptyset (&sa.sa_mask); + sa.sa_flags = 0; + + if (sigaction (SIGPIPE, &sa, NULL) != 0) + { + puts ("sigaction failed"); + return 1; + } + + if (pipe (fd) != 0) + { + puts ("pipe failed"); + return 1; + } + + if (pthread_create (&th, NULL, tf, NULL) != 0) + { + puts ("create failed"); + return 1; + } + + if (pthread_cancel (th) != 0) + { + puts ("cancel failed"); + return 1; + } + + /* This will cause the write in the child to return. */ + close (fd[0]); + + if (pthread_join (th, &r) != 0) + { + puts ("join failed"); + return 1; + } + + if (r != PTHREAD_CANCELED) + { + printf ("result is wrong: expected %p, got %p\n", PTHREAD_CANCELED, r); + return 1; + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" --- libc/linuxthreads/tst-cancel3.c.jj 2002-12-20 22:03:13.000000000 +0100 +++ libc/linuxthreads/tst-cancel3.c 2002-11-26 23:49:53.000000000 +0100 @@ -0,0 +1,98 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 <pthread.h> +#include <signal.h> +#include <stdio.h> +#include <unistd.h> + + +static int fd[2]; + + +static void * +tf (void *arg) +{ + char buf[100]; + + if (read (fd[0], buf, sizeof (buf)) == sizeof (buf)) + { + puts ("read succeeded"); + return (void *) 1l; + } + + return NULL; +} + + +static int +do_test (void) +{ + pthread_t th; + void *r; + struct sigaction sa; + + sa.sa_handler = SIG_IGN; + sigemptyset (&sa.sa_mask); + sa.sa_flags = 0; + + if (sigaction (SIGPIPE, &sa, NULL) != 0) + { + puts ("sigaction failed"); + return 1; + } + + if (pipe (fd) != 0) + { + puts ("pipe failed"); + return 1; + } + + if (pthread_create (&th, NULL, tf, NULL) != 0) + { + puts ("create failed"); + return 1; + } + + if (pthread_cancel (th) != 0) + { + puts ("cancel failed"); + return 1; + } + + /* This will cause the read in the child to return. */ + close (fd[0]); + + if (pthread_join (th, &r) != 0) + { + puts ("join failed"); + return 1; + } + + if (r != PTHREAD_CANCELED) + { + puts ("result is wrong"); + return 1; + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" --- libc/linuxthreads/tst-cancel4.c.jj 2002-12-20 22:03:13.000000000 +0100 +++ libc/linuxthreads/tst-cancel4.c 2002-12-20 21:58:50.000000000 +0100 @@ -0,0 +1,461 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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. */ + +/* NOTE: this tests functionality beyond POSIX. POSIX does not allow + exit to be called more than once. */ + +#include <errno.h> +#include <limits.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/poll.h> +#include <sys/select.h> +#include <sys/uio.h> +#include <sys/wait.h> + +/* The following interfaces are defined to be cancellation points but + tests are not yet implemented: + + accept() aio_suspend() clock_nanosleep() + close() connect() creat() + fcntl() fsync() getmsg() + getpmsg() lockf() mq_receive() + mq_send() mq_timedreceive() mq_timedsend() + msgrcv() msgsnd() msync() + open() pause() + pread() pthread_cond_timedwait() + pthread_cond_wait() pthread_join() pthread_testcancel() + putmsg() putpmsg() pwrite() + recv() + recvfrom() recvmsg() + sem_timedwait() sem_wait() send() + sendmsg() sendto() sigpause() + sigsuspend() sigtimedwait() sigwait() + sigwaitinfo() system() + tcdrain() + + Since STREAMS are not supported in the standard Linux kernel there + is no need to test the STREAMS related functions. +*/ + +/* Pipe descriptors. */ +static int fds[2]; + +/* Often used barrier for two threads. */ +static pthread_barrier_t b2; + + +static void * +tf_read (void *arg) +{ + int r = pthread_barrier_wait (&b2); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("%s: barrier_wait failed\n", __FUNCTION__); + exit (1); + } + + char buf[100]; + ssize_t s = read (fds[0], buf, sizeof (buf)); + + printf ("%s: read returns with %zd\n", __FUNCTION__, s); + + exit (1); +} + + +static void * +tf_readv (void *arg) +{ + int r = pthread_barrier_wait (&b2); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("%s: barrier_wait failed\n", __FUNCTION__); + exit (1); + } + + char buf[100]; + struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } }; + ssize_t s = readv (fds[0], iov, 1); + + printf ("%s: readv returns with %zd\n", __FUNCTION__, s); + + exit (1); +} + + +static void * +tf_write (void *arg) +{ + int r = pthread_barrier_wait (&b2); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("%s: barrier_wait failed\n", __FUNCTION__); + exit (1); + } + + char buf[100000]; + memset (buf, '\0', sizeof (buf)); + ssize_t s = write (fds[1], buf, sizeof (buf)); + + printf ("%s: write returns with %zd\n", __FUNCTION__, s); + + exit (1); +} + + +static void * +tf_writev (void *arg) +{ + int r = pthread_barrier_wait (&b2); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("%s: barrier_wait failed\n", __FUNCTION__); + exit (1); + } + + char buf[100000]; + memset (buf, '\0', sizeof (buf)); + struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } }; + ssize_t s = writev (fds[1], iov, 1); + + printf ("%s: writev returns with %zd\n", __FUNCTION__, s); + + exit (1); +} + + +static void * +tf_sleep (void *arg) +{ + int r = pthread_barrier_wait (&b2); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("%s: barrier_wait failed\n", __FUNCTION__); + exit (1); + } + + sleep (10000000); + + printf ("%s: sleep returns\n", __FUNCTION__); + + exit (1); +} + + +static void * +tf_usleep (void *arg) +{ + int r = pthread_barrier_wait (&b2); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("%s: barrier_wait failed\n", __FUNCTION__); + exit (1); + } + + usleep ((useconds_t) ULONG_MAX); + + printf ("%s: usleep returns\n", __FUNCTION__); + + exit (1); +} + + +static void * +tf_nanosleep (void *arg) +{ + int r = pthread_barrier_wait (&b2); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("%s: barrier_wait failed\n", __FUNCTION__); + exit (1); + } + + struct timespec ts = { .tv_sec = 10000000, .tv_nsec = 0 }; + while (nanosleep (&ts, &ts) != 0) + continue; + + printf ("%s: nanosleep returns\n", __FUNCTION__); + + exit (1); +} + + +static void * +tf_select (void *arg) +{ + int r = pthread_barrier_wait (&b2); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("%s: barrier_wait failed\n", __FUNCTION__); + exit (1); + } + + fd_set rfs; + FD_ZERO (&rfs); + FD_SET (fds[0], &rfs); + + int s = select (fds[0] + 1, &rfs, NULL, NULL, NULL); + + printf ("%s: select returns with %d (%s)\n", __FUNCTION__, s, + strerror (errno)); + + exit (1); +} + + +static void * +tf_pselect (void *arg) +{ + int r = pthread_barrier_wait (&b2); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("%s: barrier_wait failed\n", __FUNCTION__); + exit (1); + } + + fd_set rfs; + FD_ZERO (&rfs); + FD_SET (fds[0], &rfs); + + int s = pselect (fds[0] + 1, &rfs, NULL, NULL, NULL, NULL); + + printf ("%s: pselect returns with %d (%s)\n", __FUNCTION__, s, + strerror (errno)); + + exit (1); +} + + +static void * +tf_poll (void *arg) +{ + int r = pthread_barrier_wait (&b2); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("%s: barrier_wait failed\n", __FUNCTION__); + exit (1); + } + + struct pollfd rfs[1] = { [0] = { .fd = fds[0], .events = POLLIN } }; + + int s = poll (rfs, 1, -1); + + printf ("%s: poll returns with %d (%s)\n", __FUNCTION__, s, + strerror (errno)); + + exit (1); +} + + +static void * +tf_wait (void *arg) +{ + int r = pthread_barrier_wait (&b2); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("%s: barrier_wait failed\n", __FUNCTION__); + exit (1); + } + + pid_t pid = fork (); + if (pid == -1) + { + puts ("fork failed"); + exit (1); + } + + if (pid == 0) + { + /* Make the program disappear after a while. */ + sleep (10); + exit (0); + } + + int s = wait (NULL); + + printf ("%s: wait returns with %d (%s)\n", __FUNCTION__, s, + strerror (errno)); + + exit (1); +} + + +static void * +tf_waitpid (void *arg) +{ + int r = pthread_barrier_wait (&b2); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("%s: barrier_wait failed\n", __FUNCTION__); + exit (1); + } + + pid_t pid = fork (); + if (pid == -1) + { + puts ("fork failed"); + exit (1); + } + + if (pid == 0) + { + /* Make the program disappear after a while. */ + sleep (10); + exit (0); + } + + int s = waitpid (-1, NULL, 0); + + printf ("%s: waitpid returns with %d (%s)\n", __FUNCTION__, s, + strerror (errno)); + + exit (1); +} + + +static void * +tf_waitid (void *arg) +{ + int r = pthread_barrier_wait (&b2); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("%s: barrier_wait failed\n", __FUNCTION__); + exit (1); + } + + pid_t pid = fork (); + if (pid == -1) + { + puts ("fork failed"); + exit (1); + } + + if (pid == 0) + { + /* Make the program disappear after a while. */ + sleep (10); + exit (0); + } + + siginfo_t si; + int s = waitid (P_PID, pid, &si, 0); + + printf ("%s: waitid returns with %d (%s)\n", __FUNCTION__, s, + strerror (errno)); + + exit (1); +} + + +static struct +{ + void *(*tf) (void *); + int nb; +} tests[] = +{ + { tf_read, 2 }, + { tf_readv, 2 }, + { tf_select, 2 }, + { tf_pselect, 2 }, + { tf_poll, 2 }, + { tf_write, 2 }, + { tf_writev, 2}, + { tf_sleep, 2 }, + { tf_usleep, 2 }, + { tf_nanosleep, 2 }, + { tf_wait, 2 }, + { tf_waitid, 2 }, + { tf_waitpid, 2 }, +}; +#define ntest_tf (sizeof (tests) / sizeof (tests[0])) + + +static int +do_test (void) +{ + if (pipe (fds) != 0) + { + puts ("pipe failed"); + exit (1); + } + + int cnt; + for (cnt = 0; cnt < ntest_tf; ++cnt) + { + if (pthread_barrier_init (&b2, NULL, tests[cnt].nb) != 0) + { + puts ("b2 init failed"); + exit (1); + } + + /* read(2) test. */ + pthread_t th; + if (pthread_create (&th, NULL, tests[cnt].tf, NULL) != 0) + { + printf ("create for round %d test failed\n", cnt); + exit (1); + } + + int r = pthread_barrier_wait (&b2); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("%s: barrier_wait failed\n", __FUNCTION__); + exit (1); + } + + struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 }; + while (nanosleep (&ts, &ts) != 0) + continue; + + if (pthread_cancel (th) != 0) + { + printf ("cancel in round %d failed\n", cnt); + exit (1); + } + + void *status; + if (pthread_join (th, &status) != 0) + { + printf ("join in round %d failed\n", cnt); + exit (1); + } + if (status != PTHREAD_CANCELED) + { + printf ("thread in round %d not canceled\n", cnt); + exit (1); + } + printf ("test %d successful\n", cnt); + + if (pthread_barrier_destroy (&b2) != 0) + { + puts ("barrier_destroy failed"); + exit (1); + } + } + + return 0; +} + +#define TIMEOUT 60 +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" --- libc/linuxthreads/tst-cancel5.c.jj 2002-12-20 22:03:13.000000000 +0100 +++ libc/linuxthreads/tst-cancel5.c 2002-12-14 20:28:32.000000000 +0100 @@ -0,0 +1 @@ +#include "tst-cancel4.c" --- libc/linuxthreads/tst-cancel6.c.jj 2002-12-20 22:03:13.000000000 +0100 +++ libc/linuxthreads/tst-cancel6.c 2002-12-17 23:47:54.000000000 +0100 @@ -0,0 +1,79 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. + + 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 <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + + +static void * +tf (void *arg) +{ + char buf[100]; + fgets (buf, sizeof (buf), arg); + /* This call should never return. */ + return NULL; +} + + +static int +do_test (void) +{ + int fd[2]; + if (pipe (fd) != 0) + { + puts ("pipe failed"); + return 1; + } + + FILE *fp = fdopen (fd[0], "r"); + if (fp == NULL) + { + puts ("fdopen failed"); + return 1; + } + + pthread_t th; + if (pthread_create (&th, NULL, tf, fp) != 0) + { + puts ("pthread_create failed"); + return 1; + } + + sleep (1); + + if (pthread_cancel (th) != 0) + { + puts ("pthread_cancel failed"); + return 1; + } + + void *r; + if (pthread_join (th, &r) != 0) + { + puts ("pthread_join failed"); + return 1; + } + + return r != PTHREAD_CANCELED; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" --- libc/sysdeps/generic/libc-tls.c.jj 2002-12-10 15:08:54.000000000 +0100 +++ libc/sysdeps/generic/libc-tls.c 2002-12-20 20:37:00.000000000 +0100 @@ -135,8 +135,13 @@ __libc_setup_tls (size_t tcbsize, size_t } if (memsz == 0 && tcbsize <= TLS_INIT_TCB_SIZE) - /* We do not need a TLS block and no thread descriptor. */ - return; + { + /* We do not need a TLS block and no thread descriptor. */ +#ifdef NONTLS_INIT_TP + NONTLS_INIT_TP; +#endif + return; + } /* We have to set up the TCB block which also (possibly) contains @@ -249,4 +254,16 @@ __pthread_initialize_minimal (void) { __libc_setup_tls (TLS_INIT_TCB_SIZE, TLS_INIT_TCB_ALIGN); } + +#elif defined NONTLS_INIT_TP + +/* This is the minimal initialization function used when libpthread is + not used. */ +void +__attribute__ ((weak)) +__pthread_initialize_minimal (void) +{ + NONTLS_INIT_TP; +} + #endif --- libc/sysdeps/generic/libc-start.c.jj 2002-12-10 15:08:54.000000000 +0100 +++ libc/sysdeps/generic/libc-start.c 2002-12-20 22:00:08.000000000 +0100 @@ -32,7 +32,7 @@ extern void *__libc_stack_end; #ifndef SHARED # include <dl-osinfo.h> extern void __pthread_initialize_minimal (void) -# if !(USE_TLS - 0) +# if !(USE_TLS - 0) && !defined NONTLS_INIT_TP __attribute__ ((weak)) # endif ; @@ -97,7 +97,7 @@ BP_SYM (__libc_start_main) (int (*main) we need to setup errno. If there is no thread library and we handle TLS the function is defined in the libc to initialized the TLS handling. */ -# if !(USE_TLS - 0) +# if !(USE_TLS - 0) && !defined NONTLS_INIT_TP if (__pthread_initialize_minimal) # endif __pthread_initialize_minimal (); --- libc/sysdeps/unix/common/pause.c.jj 2001-08-23 18:50:34.000000000 +0200 +++ libc/sysdeps/unix/common/pause.c 2002-12-20 21:33:08.000000000 +0100 @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1996 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1996, 2002 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 @@ -18,7 +18,7 @@ #include <signal.h> #include <unistd.h> - +#include <sysdep-cancel.h> /* Suspend the process until a signal arrives. This always returns -1 and sets errno to EINTR. */ @@ -26,6 +26,12 @@ int __libc_pause (void) { - return __sigpause (__sigblock (0), 0); + if (SINGLE_THREAD_P) + return __sigpause (__sigblock (0), 0); + + int oldtype = LIBC_CANCEL_ASYNC (); + int result = __sigpause (__sigblock (0), 0); + LIBC_CANCEL_RESET (oldtype); + return result; } weak_alias (__libc_pause, pause) --- libc/sysdeps/unix/sysv/linux/ia64/sysdep.h.jj 2002-12-10 15:09:30.000000000 +0100 +++ libc/sysdeps/unix/sysv/linux/ia64/sysdep.h 2002-12-20 14:00:36.000000000 +0100 @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999. Based on code originally written by David Mosberger-Tang @@ -83,7 +83,7 @@ #define PSEUDO(name, syscall_name, args) \ ENTRY(name) \ DO_CALL (SYS_ify(syscall_name)); \ - cmp.eq p6,p0=-1,r10;; \ + cmp.eq p6,p0=-1,r10; \ (p6) br.cond.spnt.few __syscall_error; #define DO_CALL(num) \ @@ -102,11 +102,98 @@ #else /* not __ASSEMBLER__ */ -/* Define a macro which expands into the inline wrapper code for a system - call. */ -#if 0 +/* On IA-64 we have stacked registers for passing arguments. The + "out" registers end up being the called function's "in" + registers. + + Also, since we have plenty of registers we have two return values + from a syscall. r10 is set to -1 on error, whilst r8 contains the + (non-negative) errno on error or the return value on success. + */ #undef INLINE_SYSCALL -#define INLINE_SYSCALL(name, nr, args...) __##name (args) -#endif +#define INLINE_SYSCALL(name, nr, args...) \ + ({ \ + register long _r8 asm ("r8"); \ + register long _r10 asm ("r10"); \ + register long _r15 asm ("r15") = __NR_##name; \ + long _retval; \ + LOAD_ARGS_##nr (args); \ + __asm __volatile ("break %3;;\n\t" \ + : "=r" (_r8), "=r" (_r10), "=r" (_r15) \ + : "i" (__BREAK_SYSCALL), "2" (_r15) \ + ASM_ARGS_##nr \ + : "memory" ASM_CLOBBERS_##nr); \ + _retval = _r8; \ + if (_r10 == -1) \ + { \ + __set_errno (_retval); \ + _retval = -1; \ + } \ + _retval; }) + +#undef INTERNAL_SYSCALL +#define INTERNAL_SYSCALL(name, nr, args...) \ + ({ \ + register long _r8 asm ("r8"); \ + register long _r10 asm ("r10"); \ + register long _r15 asm ("r15") = __NR_##name; \ + long _retval; \ + LOAD_ARGS_##nr (args); \ + __asm __volatile ("break %3;;\n\t" \ + : "=r" (_r8), "=r" (_r10), "=r" (_r15) \ + : "i" (__BREAK_SYSCALL), "2" (_r15) \ + ASM_ARGS_##nr \ + : "memory" ASM_CLOBBERS_##nr); \ + _retval = _r8; \ + if (_r10 == -1) \ + _retval = -_retval; \ + _retval; }) + +#undef INTERNAL_SYSCALL_ERROR_P +#define INTERNAL_SYSCALL_ERROR_P(val) ((unsigned long) (val) >= -4095UL) + +#undef INTERNAL_SYSCALL_ERRNO +#define INTERNAL_SYSCALL_ERRNO(val) (-(val)) + +#define LOAD_ARGS_0() do { } while (0) +#define LOAD_ARGS_1(out0) \ + register long _out0 asm ("out0") = (long) (out0); \ + LOAD_ARGS_0 () +#define LOAD_ARGS_2(out0, out1) \ + register long _out1 asm ("out1") = (long) (out1); \ + LOAD_ARGS_1 (out0) +#define LOAD_ARGS_3(out0, out1, out2) \ + register long _out2 asm ("out2") = (long) (out2); \ + LOAD_ARGS_2 (out0, out1) +#define LOAD_ARGS_4(out0, out1, out2, out3) \ + register long _out3 asm ("out3") = (long) (out3); \ + LOAD_ARGS_3 (out0, out1, out2) +#define LOAD_ARGS_5(out0, out1, out2, out3, out4) \ + register long _out4 asm ("out4") = (long) (out4); \ + LOAD_ARGS_4 (out0, out1, out2, out3) + +#define ASM_ARGS_0 +#define ASM_ARGS_1 ASM_ARGS_0, "r" (_out0) +#define ASM_ARGS_2 ASM_ARGS_1, "r" (_out1) +#define ASM_ARGS_3 ASM_ARGS_2, "r" (_out2) +#define ASM_ARGS_4 ASM_ARGS_3, "r" (_out3) +#define ASM_ARGS_5 ASM_ARGS_4, "r" (_out4) + +#define ASM_CLOBBERS_0 ASM_CLOBBERS_1, "out0" +#define ASM_CLOBBERS_1 ASM_CLOBBERS_2, "out1" +#define ASM_CLOBBERS_2 ASM_CLOBBERS_3, "out2" +#define ASM_CLOBBERS_3 ASM_CLOBBERS_4, "out3" +#define ASM_CLOBBERS_4 ASM_CLOBBERS_5, "out4" +#define ASM_CLOBBERS_5 , "out5", "out6", "out7", \ + /* Non-stacked integer registers, minus r8, r10, r15. */ \ + "r2", "r3", "r9", "r11", "r12", "r13", "r14", "r16", "r17", "r18", \ + "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", \ + "r28", "r29", "r30", "r31", \ + /* Predicate registers. */ \ + "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", \ + /* Non-rotating fp registers. */ \ + "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ + /* Branch registers. */ \ + "b6", "b7" #endif /* not __ASSEMBLER__ */ --- libc/nptl/Makefile.jj 2002-12-20 12:17:13.000000000 +0100 +++ libc/nptl/Makefile 2002-12-20 21:58:19.000000000 +0100 @@ -214,8 +214,10 @@ $(addprefix $(objpfx), \ $(tests) $(test-srcs))): $(objpfx)libpthread.so \ $(objpfx)libpthread_nonshared.a $(objpfx)tst-unload: $(common-objpfx)dlfcn/libdl.so +# $(objpfx)../libc.so is used instead of $(common-objpfx)libc.so, +# since otherwise libpthread.so comes before libc.so when linking. $(addprefix $(objpfx), $(tests-reverse)): \ - $(common-objpfx)libc.so $(objpfx)libpthread.so \ + $(objpfx)../libc.so $(objpfx)libpthread.so \ $(objpfx)libpthread_nonshared.a $(addprefix $(objpfx),$(tests-static)): $(objpfx)libpthread.a else --- libc/nptl/tst-cancel4.c.jj 2002-11-26 23:50:02.000000000 +0100 +++ libc/nptl/tst-cancel4.c 2002-12-20 21:58:50.000000000 +0100 @@ -113,7 +113,7 @@ tf_write (void *arg) exit (1); } - char buf[10000]; + char buf[100000]; memset (buf, '\0', sizeof (buf)); ssize_t s = write (fds[1], buf, sizeof (buf)); @@ -133,7 +133,7 @@ tf_writev (void *arg) exit (1); } - char buf[10000]; + char buf[100000]; memset (buf, '\0', sizeof (buf)); struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } }; ssize_t s = writev (fds[1], iov, 1); @@ -172,7 +172,7 @@ tf_usleep (void *arg) exit (1); } - usleep (ULONG_MAX); + usleep ((useconds_t) ULONG_MAX); printf ("%s: usleep returns\n", __FUNCTION__); Jakub
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |