diff options
author | Simon Josefsson <simon@josefsson.org> | 2011-05-20 22:37:02 +0200 |
---|---|---|
committer | Simon Josefsson <simon@josefsson.org> | 2011-05-20 22:37:02 +0200 |
commit | 2bd4123f0ad3b694e8cfadc15d0fe1b16e36bc49 (patch) | |
tree | afe003c7902bc7367b573967c6c217956bfdfa48 /gl/tests | |
parent | 14cdffd508a834f0df1935732455c40432ad36b0 (diff) | |
download | gnutls-2bd4123f0ad3b694e8cfadc15d0fe1b16e36bc49.tar.gz |
Update gnulib files.
Diffstat (limited to 'gl/tests')
-rw-r--r-- | gl/tests/Makefile.am | 33 | ||||
-rw-r--r-- | gl/tests/dummy.c | 42 | ||||
-rw-r--r-- | gl/tests/glthread/thread.c | 218 | ||||
-rw-r--r-- | gl/tests/glthread/thread.h | 376 | ||||
-rw-r--r-- | gl/tests/glthread/yield.h | 121 | ||||
-rw-r--r-- | gl/tests/test-intprops.c | 456 | ||||
-rw-r--r-- | gl/tests/test-lock.c | 601 | ||||
-rw-r--r-- | gl/tests/test-strerror.c | 18 | ||||
-rw-r--r-- | gl/tests/test-strerror_r.c | 112 |
9 files changed, 267 insertions, 1710 deletions
diff --git a/gl/tests/Makefile.am b/gl/tests/Makefile.am index 703b7b45d5..4d0a31733c 100644 --- a/gl/tests/Makefile.am +++ b/gl/tests/Makefile.am @@ -10,7 +10,7 @@ # # Generated by gnulib-tool. -AUTOMAKE_OPTIONS = 1.5 foreign subdir-objects +AUTOMAKE_OPTIONS = 1.5 foreign SUBDIRS = . TESTS = @@ -267,7 +267,7 @@ EXTRA_DIST += signature.h test-gettimeofday.c TESTS += test-intprops check_PROGRAMS += test-intprops -EXTRA_DIST += test-intprops.c macros.h +EXTRA_DIST += test-intprops.c ## end gnulib module intprops-tests @@ -321,15 +321,6 @@ EXTRA_DIST += test-inttypes.c ## end gnulib module inttypes-tests -## begin gnulib module lock-tests - -TESTS += test-lock -check_PROGRAMS += test-lock -test_lock_LDADD = $(LDADD) @LIBMULTITHREAD@ @YIELD_LIB@ -EXTRA_DIST += test-lock.c - -## end gnulib module lock-tests - ## begin gnulib module memchr-tests TESTS += test-memchr @@ -428,14 +419,6 @@ EXTRA_DIST += test-strerror.c signature.h macros.h ## end gnulib module strerror-tests -## begin gnulib module strerror_r-posix-tests - -TESTS += test-strerror_r -check_PROGRAMS += test-strerror_r -EXTRA_DIST += test-strerror_r.c signature.h macros.h - -## end gnulib module strerror_r-posix-tests - ## begin gnulib module string-tests TESTS += test-string @@ -492,12 +475,6 @@ EXTRA_DIST += test-sys_uio.c ## end gnulib module sys_uio-tests -## begin gnulib module thread - -libtests_a_SOURCES += glthread/thread.h glthread/thread.c - -## end gnulib module thread - ## begin gnulib module time-tests TESTS += test-time @@ -594,11 +571,11 @@ EXTRA_DIST += test-wchar.c ## end gnulib module wchar-tests -## begin gnulib module yield +## begin gnulib module dummy -libtests_a_SOURCES += glthread/yield.h +libtests_a_SOURCES += dummy.c -## end gnulib module yield +## end gnulib module dummy # Clean up after Solaris cc. clean-local: diff --git a/gl/tests/dummy.c b/gl/tests/dummy.c new file mode 100644 index 0000000000..c958ea05d8 --- /dev/null +++ b/gl/tests/dummy.c @@ -0,0 +1,42 @@ +/* A dummy file, to prevent empty libraries from breaking builds. + Copyright (C) 2004, 2007, 2009-2011 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* Some systems, reportedly OpenBSD and Mac OS X, refuse to create + libraries without any object files. You might get an error like: + + > ar cru .libs/libgl.a + > ar: no archive members specified + + Compiling this file, and adding its object file to the library, will + prevent the library from being empty. */ + +/* Some systems, such as Solaris with cc 5.0, refuse to work with libraries + that don't export any symbol. You might get an error like: + + > cc ... libgnu.a + > ild: (bad file) garbled symbol table in archive ../gllib/libgnu.a + + Compiling this file, and adding its object file to the library, will + prevent the library from exporting no symbols. */ + +#ifdef __sun +/* This declaration ensures that the library will export at least 1 symbol. */ +int gl_dummy_symbol; +#else +/* This declaration is solely to ensure that after preprocessing + this file is never empty. */ +typedef int dummy; +#endif diff --git a/gl/tests/glthread/thread.c b/gl/tests/glthread/thread.c deleted file mode 100644 index bb40092fc2..0000000000 --- a/gl/tests/glthread/thread.c +++ /dev/null @@ -1,218 +0,0 @@ -/* Creating and controlling threads. - Copyright (C) 2005-2011 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Bruno Haible <bruno@clisp.org>, 2005. - Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h, - gthr-win32.h. */ - -#include <config.h> - -/* Specification. */ -#include "glthread/thread.h" - -#include <stdlib.h> -#include "glthread/lock.h" - -/* ========================================================================= */ - -#if USE_WIN32_THREADS - -#include <process.h> - -/* -------------------------- gl_thread_t datatype -------------------------- */ - -/* The Thread-Local Storage (TLS) key that allows to access each thread's - 'struct gl_thread_struct *' pointer. */ -static DWORD self_key = (DWORD)-1; - -/* Initializes self_key. This function must only be called once. */ -static void -do_init_self_key (void) -{ - self_key = TlsAlloc (); - /* If this fails, we're hosed. */ - if (self_key == (DWORD)-1) - abort (); -} - -/* Initializes self_key. */ -static void -init_self_key (void) -{ - gl_once_define(static, once) - gl_once (once, do_init_self_key); -} - -/* This structure contains information about a thread. - It is stored in TLS under key self_key. */ -struct gl_thread_struct -{ - /* Fields for managing the handle. */ - HANDLE volatile handle; - CRITICAL_SECTION handle_lock; - /* Fields for managing the exit value. */ - void * volatile result; - /* Fields for managing the thread start. */ - void * (*func) (void *); - void *arg; -}; - -/* Return a real HANDLE object for the current thread. */ -static inline HANDLE -get_current_thread_handle (void) -{ - HANDLE this_handle; - - /* GetCurrentThread() returns a pseudo-handle, i.e. only a symbolic - identifier, not a real handle. */ - if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (), - GetCurrentProcess (), &this_handle, - 0, FALSE, DUPLICATE_SAME_ACCESS)) - abort (); - return this_handle; -} - -gl_thread_t -gl_thread_self_func (void) -{ - gl_thread_t thread; - - if (self_key == (DWORD)-1) - init_self_key (); - thread = TlsGetValue (self_key); - if (thread == NULL) - { - /* This happens only in threads that have not been created through - glthread_create(), such as the main thread. */ - for (;;) - { - thread = - (struct gl_thread_struct *) - malloc (sizeof (struct gl_thread_struct)); - if (thread != NULL) - break; - /* Memory allocation failed. There is not much we can do. Have to - busy-loop, waiting for the availability of memory. */ - Sleep (1); - } - - thread->handle = get_current_thread_handle (); - InitializeCriticalSection (&thread->handle_lock); - thread->result = NULL; /* just to be deterministic */ - TlsSetValue (self_key, thread); - } - return thread; -} - -/* The main function of a freshly creating thread. It's a wrapper around - the FUNC and ARG arguments passed to glthread_create_func. */ -static unsigned int WINAPI -wrapper_func (void *varg) -{ - struct gl_thread_struct *thread = (struct gl_thread_struct *)varg; - - EnterCriticalSection (&thread->handle_lock); - /* Create a new handle for the thread only if the parent thread did not yet - fill in the handle. */ - if (thread->handle == NULL) - thread->handle = get_current_thread_handle (); - LeaveCriticalSection (&thread->handle_lock); - - if (self_key == (DWORD)-1) - init_self_key (); - TlsSetValue (self_key, thread); - - /* Run the thread. Store the exit value if the thread was not terminated - otherwise. */ - thread->result = thread->func (thread->arg); - return 0; -} - -int -glthread_create_func (gl_thread_t *threadp, void * (*func) (void *), void *arg) -{ - struct gl_thread_struct *thread = - (struct gl_thread_struct *) malloc (sizeof (struct gl_thread_struct)); - if (thread == NULL) - return ENOMEM; - thread->handle = NULL; - InitializeCriticalSection (&thread->handle_lock); - thread->result = NULL; /* just to be deterministic */ - thread->func = func; - thread->arg = arg; - - { - unsigned int thread_id; - HANDLE thread_handle; - - thread_handle = (HANDLE) - _beginthreadex (NULL, 100000, wrapper_func, thread, 0, &thread_id); - /* calls CreateThread with the same arguments */ - if (thread_handle == NULL) - { - DeleteCriticalSection (&thread->handle_lock); - free (thread); - return EAGAIN; - } - - EnterCriticalSection (&thread->handle_lock); - if (thread->handle == NULL) - thread->handle = thread_handle; - else - /* thread->handle was already set by the thread itself. */ - CloseHandle (thread_handle); - LeaveCriticalSection (&thread->handle_lock); - - *threadp = thread; - return 0; - } -} - -int -glthread_join_func (gl_thread_t thread, void **retvalp) -{ - if (thread == NULL) - return EINVAL; - - if (thread == gl_thread_self ()) - return EDEADLK; - - if (WaitForSingleObject (thread->handle, INFINITE) == WAIT_FAILED) - return EINVAL; - - if (retvalp != NULL) - *retvalp = thread->result; - - DeleteCriticalSection (&thread->handle_lock); - CloseHandle (thread->handle); - free (thread); - - return 0; -} - -int -gl_thread_exit_func (void *retval) -{ - gl_thread_t thread = gl_thread_self (); - thread->result = retval; - _endthreadex (0); /* calls ExitThread (0) */ - abort (); -} - -#endif - -/* ========================================================================= */ diff --git a/gl/tests/glthread/thread.h b/gl/tests/glthread/thread.h deleted file mode 100644 index 370f09a378..0000000000 --- a/gl/tests/glthread/thread.h +++ /dev/null @@ -1,376 +0,0 @@ -/* Creating and controlling threads. - Copyright (C) 2005-2011 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Bruno Haible <bruno@clisp.org>, 2005. - Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h, - gthr-win32.h. */ - -/* This file contains primitives for creating and controlling threads. - - Thread data type: gl_thread_t. - - Creating a thread: - thread = gl_thread_create (func, arg); - Or with control of error handling: - err = glthread_create (&thread, func, arg); - extern int glthread_create (gl_thread_t *result, - void *(*func) (void *), void *arg); - - Querying and changing the signal mask of a thread (not supported on all - platforms): - gl_thread_sigmask (how, newmask, oldmask); - Or with control of error handling: - err = glthread_sigmask (how, newmask, oldmask); - extern int glthread_sigmask (int how, const sigset_t *newmask, sigset_t *oldmask); - - Waiting for termination of another thread: - gl_thread_join (thread, &return_value); - Or with control of error handling: - err = glthread_join (thread, &return_value); - extern int glthread_join (gl_thread_t thread, void **return_value_ptr); - - Getting a reference to the current thread: - current = gl_thread_self (); - extern gl_thread_t gl_thread_self (void); - - Terminating the current thread: - gl_thread_exit (return_value); - extern void gl_thread_exit (void *return_value) __attribute__ ((noreturn)); - - Requesting custom code to be executed at fork() time(not supported on all - platforms): - gl_thread_atfork (prepare_func, parent_func, child_func); - Or with control of error handling: - err = glthread_atfork (prepare_func, parent_func, child_func); - extern int glthread_atfork (void (*prepare_func) (void), - void (*parent_func) (void), - void (*child_func) (void)); - Note that even on platforms where this is supported, use of fork() and - threads together is problematic, see - <http://lists.gnu.org/archive/html/bug-gnulib/2008-08/msg00062.html> - */ - - -#ifndef _GLTHREAD_THREAD_H -#define _GLTHREAD_THREAD_H - -#include <errno.h> -#include <stdlib.h> - -/* ========================================================================= */ - -#if USE_POSIX_THREADS - -/* Use the POSIX threads library. */ - -# include <pthread.h> - -# ifdef __cplusplus -extern "C" { -# endif - -# if PTHREAD_IN_USE_DETECTION_HARD - -/* The pthread_in_use() detection needs to be done at runtime. */ -# define pthread_in_use() \ - glthread_in_use () -extern int glthread_in_use (void); - -# endif - -# if USE_POSIX_THREADS_WEAK - -/* Use weak references to the POSIX threads library. */ - -/* Weak references avoid dragging in external libraries if the other parts - of the program don't use them. Here we use them, because we don't want - every program that uses libintl to depend on libpthread. This assumes - that libpthread would not be loaded after libintl; i.e. if libintl is - loaded first, by an executable that does not depend on libpthread, and - then a module is dynamically loaded that depends on libpthread, libintl - will not be multithread-safe. */ - -/* The way to test at runtime whether libpthread is present is to test - whether a function pointer's value, such as &pthread_mutex_init, is - non-NULL. However, some versions of GCC have a bug through which, in - PIC mode, &foo != NULL always evaluates to true if there is a direct - call to foo(...) in the same function. To avoid this, we test the - address of a function in libpthread that we don't use. */ - -# pragma weak pthread_create -# pragma weak pthread_sigmask -# pragma weak pthread_join -# ifndef pthread_self -# pragma weak pthread_self -# endif -# pragma weak pthread_exit -# if HAVE_PTHREAD_ATFORK -# pragma weak pthread_atfork -# endif - -# if !PTHREAD_IN_USE_DETECTION_HARD -# pragma weak pthread_cancel -# define pthread_in_use() (pthread_cancel != NULL) -# endif - -# else - -# if !PTHREAD_IN_USE_DETECTION_HARD -# define pthread_in_use() 1 -# endif - -# endif - -/* -------------------------- gl_thread_t datatype -------------------------- */ - -/* This choice of gl_thread_t assumes that - pthread_equal (a, b) is equivalent to ((a) == (b)). - This is the case on all platforms in use in 2008. */ -typedef pthread_t gl_thread_t; -# define glthread_create(THREADP, FUNC, ARG) \ - (pthread_in_use () ? pthread_create (THREADP, NULL, FUNC, ARG) : ENOSYS) -# define glthread_sigmask(HOW, SET, OSET) \ - (pthread_in_use () ? pthread_sigmask (HOW, SET, OSET) : 0) -# define glthread_join(THREAD, RETVALP) \ - (pthread_in_use () ? pthread_join (THREAD, RETVALP) : 0) -# define gl_thread_self() \ - (pthread_in_use () ? (void *) pthread_self () : NULL) -# define gl_thread_exit(RETVAL) \ - (pthread_in_use () ? pthread_exit (RETVAL) : 0) - -# if HAVE_PTHREAD_ATFORK -# define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) \ - (pthread_in_use () ? pthread_atfork (PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) : 0) -# else -# define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0 -# endif - -# ifdef __cplusplus -} -# endif - -#endif - -/* ========================================================================= */ - -#if USE_PTH_THREADS - -/* Use the GNU Pth threads library. */ - -# include <pth.h> - -# ifdef __cplusplus -extern "C" { -# endif - -# if USE_PTH_THREADS_WEAK - -/* Use weak references to the GNU Pth threads library. */ - -# pragma weak pth_spawn -# pragma weak pth_sigmask -# pragma weak pth_join -# pragma weak pth_self -# pragma weak pth_exit - -# pragma weak pth_cancel -# define pth_in_use() (pth_cancel != NULL) - -# else - -# define pth_in_use() 1 - -# endif -/* -------------------------- gl_thread_t datatype -------------------------- */ - -typedef pth_t gl_thread_t; -# define glthread_create(THREADP, FUNC, ARG) \ - (pth_in_use () ? ((*(THREADP) = pth_spawn (NULL, FUNC, ARG)) ? 0 : errno) : 0) -# define glthread_sigmask(HOW, SET, OSET) \ - (pth_in_use () && !pth_sigmask (HOW, SET, OSET) ? errno : 0) -# define glthread_join(THREAD, RETVALP) \ - (pth_in_use () && !pth_join (THREAD, RETVALP) ? errno : 0) -# define gl_thread_self() \ - (pth_in_use () ? (void *) pth_self () : 0) -# define gl_thread_exit(RETVAL) \ - (pth_in_use () ? pth_exit (RETVAL) : 0) -# define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0 - -# ifdef __cplusplus -} -# endif - -#endif - -/* ========================================================================= */ - -#if USE_SOLARIS_THREADS - -/* Use the old Solaris threads library. */ - -# include <thread.h> -# include <synch.h> - -# ifdef __cplusplus -extern "C" { -# endif - -# if USE_SOLARIS_THREADS_WEAK - -/* Use weak references to the old Solaris threads library. */ - -# pragma weak thr_create -# pragma weak thr_join -# pragma weak thr_self -# pragma weak thr_exit - -# pragma weak thr_suspend -# define thread_in_use() (thr_suspend != NULL) - -# else - -# define thread_in_use() 1 - -# endif - -/* -------------------------- gl_thread_t datatype -------------------------- */ - -typedef thread_t gl_thread_t; -# define glthread_create(THREADP, FUNC, ARG) \ - (thread_in_use () ? thr_create (NULL, 0, FUNC, ARG, 0, THREADP) : 0) -# define glthread_sigmask(HOW, SET, OSET) \ - (thread_in_use () ? sigprocmask (HOW, SET, OSET) : 0) -# define glthread_join(THREAD, RETVALP) \ - (thread_in_use () ? thr_join (THREAD, NULL, RETVALP) : 0) -# define gl_thread_self() \ - (thread_in_use () ? (void *) thr_self () : 0) -# define gl_thread_exit(RETVAL) \ - (thread_in_use () ? thr_exit (RETVAL) : 0) -# define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0 - -# ifdef __cplusplus -} -# endif - -#endif - -/* ========================================================================= */ - -#if USE_WIN32_THREADS - -# include <windows.h> - -# ifdef __cplusplus -extern "C" { -# endif - -/* -------------------------- gl_thread_t datatype -------------------------- */ - -/* The gl_thread_t is a pointer to a structure in memory. - Why not the thread handle? If it were the thread handle, it would be hard - to implement gl_thread_self() (since GetCurrentThread () returns a pseudo- - handle, DuplicateHandle (GetCurrentThread ()) returns a handle that must be - closed afterwards, and there is no function for quickly retrieving a thread - handle from its id). - Why not the thread id? I tried it. It did not work: Sometimes ids appeared - that did not belong to running threads, and glthread_join failed with ESRCH. - */ -typedef struct gl_thread_struct *gl_thread_t; -# define glthread_create(THREADP, FUNC, ARG) \ - glthread_create_func (THREADP, FUNC, ARG) -# define glthread_sigmask(HOW, SET, OSET) \ - /* unsupported */ 0 -# define glthread_join(THREAD, RETVALP) \ - glthread_join_func (THREAD, RETVALP) -# define gl_thread_self() \ - gl_thread_self_func () -# define gl_thread_exit(RETVAL) \ - gl_thread_exit_func (RETVAL) -# define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0 -extern int glthread_create_func (gl_thread_t *threadp, void * (*func) (void *), void *arg); -extern int glthread_join_func (gl_thread_t thread, void **retvalp); -extern gl_thread_t gl_thread_self_func (void); -extern int gl_thread_exit_func (void *retval); - -# ifdef __cplusplus -} -# endif - -#endif - -/* ========================================================================= */ - -#if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS || USE_WIN32_THREADS) - -/* Provide dummy implementation if threads are not supported. */ - -typedef int gl_thread_t; -# define glthread_create(THREADP, FUNC, ARG) ENOSYS -# define glthread_sigmask(HOW, SET, OSET) 0 -# define glthread_join(THREAD, RETVALP) 0 -# define gl_thread_self() NULL -# define gl_thread_exit(RETVAL) 0 -# define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0 - -#endif - -/* ========================================================================= */ - -/* Macros with built-in error handling. */ - -#ifdef __cplusplus -extern "C" { -#endif - -static inline gl_thread_t -gl_thread_create (void *(*func) (void *arg), void *arg) -{ - gl_thread_t thread; - int ret; - - ret = glthread_create (&thread, func, arg); - if (ret != 0) - abort (); - return thread; -} -#define gl_thread_sigmask(HOW, SET, OSET) \ - do \ - { \ - if (glthread_sigmask (HOW, SET, OSET)) \ - abort (); \ - } \ - while (0) -#define gl_thread_join(THREAD, RETVAL) \ - do \ - { \ - if (glthread_join (THREAD, RETVAL)) \ - abort (); \ - } \ - while (0) -#define gl_thread_atfork(PREPARE, PARENT, CHILD) \ - do \ - { \ - if (glthread_atfork (PREPARE, PARENT, CHILD)) \ - abort (); \ - } \ - while (0) - -#ifdef __cplusplus -} -#endif - -#endif /* _GLTHREAD_THREAD_H */ diff --git a/gl/tests/glthread/yield.h b/gl/tests/glthread/yield.h deleted file mode 100644 index 4eb1cb845b..0000000000 --- a/gl/tests/glthread/yield.h +++ /dev/null @@ -1,121 +0,0 @@ -/* Yielding the processor to other threads and processes. - Copyright (C) 2005-2011 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* This file contains a primitive for yielding the processor to other threads. - extern void gl_thread_yield (void); - */ - -#ifndef _GLTHREAD_YIELD_H -#define _GLTHREAD_YIELD_H - -#include <errno.h> - -/* ========================================================================= */ - -#if USE_POSIX_THREADS - -/* Use the POSIX threads library. */ - -# include <sched.h> - -# ifdef __cplusplus -extern "C" { -# endif - -# define gl_thread_yield() \ - sched_yield () - -# ifdef __cplusplus -} -# endif - -#endif - -/* ========================================================================= */ - -#if USE_PTH_THREADS - -/* Use the GNU Pth threads library. */ - -# include <pth.h> - -# ifdef __cplusplus -extern "C" { -# endif - -# define gl_thread_yield() \ - pth_yield (NULL) - -# ifdef __cplusplus -} -# endif - -#endif - -/* ========================================================================= */ - -#if USE_SOLARIS_THREADS - -/* Use the old Solaris threads library. */ - -# include <thread.h> - -# ifdef __cplusplus -extern "C" { -# endif - -# define gl_thread_yield() \ - thr_yield () - -# ifdef __cplusplus -} -# endif - -#endif - -/* ========================================================================= */ - -#if USE_WIN32_THREADS - -# include <windows.h> - -# ifdef __cplusplus -extern "C" { -# endif - -# define gl_thread_yield() \ - Sleep (0) - -# ifdef __cplusplus -} -# endif - -#endif - -/* ========================================================================= */ - -#if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS || USE_WIN32_THREADS) - -/* Provide dummy implementation if threads are not supported. */ - -# define gl_thread_yield() 0 - -#endif - -/* ========================================================================= */ - -#endif /* _GLTHREAD_YIELD_H */ diff --git a/gl/tests/test-intprops.c b/gl/tests/test-intprops.c index 8fc582b90f..aae261432a 100644 --- a/gl/tests/test-intprops.c +++ b/gl/tests/test-intprops.c @@ -24,246 +24,230 @@ #include <stdbool.h> #include <inttypes.h> -#include "macros.h" - -/* VERIFY (X) uses a static assertion for compilers that are known to work, - and falls back on a dynamic assertion for other compilers. - These tests should be checkable via 'verify' rather than 'ASSERT', but - using 'verify' would run into a bug with HP-UX 11.23 cc; see - <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00401.html>. */ -#if __GNUC__ || __SUNPRO_C -# define VERIFY(x) do { verify (x); } while (0) -#else -# define VERIFY(x) ASSERT (x) +/* TYPE_IS_INTEGER. */ +verify (TYPE_IS_INTEGER (bool)); +verify (TYPE_IS_INTEGER (char)); +verify (TYPE_IS_INTEGER (signed char)); +verify (TYPE_IS_INTEGER (unsigned char)); +verify (TYPE_IS_INTEGER (short int)); +verify (TYPE_IS_INTEGER (unsigned short int)); +verify (TYPE_IS_INTEGER (int)); +verify (TYPE_IS_INTEGER (unsigned int)); +verify (TYPE_IS_INTEGER (long int)); +verify (TYPE_IS_INTEGER (unsigned long int)); +verify (TYPE_IS_INTEGER (intmax_t)); +verify (TYPE_IS_INTEGER (uintmax_t)); +verify (! TYPE_IS_INTEGER (float)); +verify (! TYPE_IS_INTEGER (double)); +verify (! TYPE_IS_INTEGER (long double)); + +/* Integer representation. */ +verify (INT_MIN + INT_MAX < 0 + ? (TYPE_TWOS_COMPLEMENT (int) + && ! TYPE_ONES_COMPLEMENT (int) && ! TYPE_SIGNED_MAGNITUDE (int)) + : (! TYPE_TWOS_COMPLEMENT (int) + && (TYPE_ONES_COMPLEMENT (int) || TYPE_SIGNED_MAGNITUDE (int)))); + +/* TYPE_SIGNED. */ +/* verify (! TYPE_SIGNED (bool)); */ /* not guaranteed by gnulib substitute */ +verify (TYPE_SIGNED (signed char)); +verify (! TYPE_SIGNED (unsigned char)); +verify (TYPE_SIGNED (short int)); +verify (! TYPE_SIGNED (unsigned short int)); +verify (TYPE_SIGNED (int)); +verify (! TYPE_SIGNED (unsigned int)); +verify (TYPE_SIGNED (long int)); +verify (! TYPE_SIGNED (unsigned long int)); +verify (TYPE_SIGNED (intmax_t)); +verify (! TYPE_SIGNED (uintmax_t)); +verify (TYPE_SIGNED (float)); +verify (TYPE_SIGNED (double)); +verify (TYPE_SIGNED (long double)); + +/* TYPE_MINIMUM, TYPE_MAXIMUM. */ +verify (TYPE_MINIMUM (char) == CHAR_MIN); +verify (TYPE_MAXIMUM (char) == CHAR_MAX); +verify (TYPE_MINIMUM (unsigned char) == 0); +verify (TYPE_MAXIMUM (unsigned char) == UCHAR_MAX); +verify (TYPE_MINIMUM (signed char) == SCHAR_MIN); +verify (TYPE_MAXIMUM (signed char) == SCHAR_MAX); +verify (TYPE_MINIMUM (short int) == SHRT_MIN); +verify (TYPE_MAXIMUM (short int) == SHRT_MAX); +verify (TYPE_MINIMUM (unsigned short int) == 0); +verify (TYPE_MAXIMUM (unsigned short int) == USHRT_MAX); +verify (TYPE_MINIMUM (int) == INT_MIN); +verify (TYPE_MAXIMUM (int) == INT_MAX); +verify (TYPE_MINIMUM (unsigned int) == 0); +verify (TYPE_MAXIMUM (unsigned int) == UINT_MAX); +verify (TYPE_MINIMUM (long int) == LONG_MIN); +verify (TYPE_MAXIMUM (long int) == LONG_MAX); +verify (TYPE_MINIMUM (unsigned long int) == 0); +verify (TYPE_MAXIMUM (unsigned long int) == ULONG_MAX); +verify (TYPE_MINIMUM (intmax_t) == INTMAX_MIN); +verify (TYPE_MAXIMUM (intmax_t) == INTMAX_MAX); +verify (TYPE_MINIMUM (uintmax_t) == 0); +verify (TYPE_MAXIMUM (uintmax_t) == UINTMAX_MAX); + +/* INT_BITS_STRLEN_BOUND. */ +verify (INT_BITS_STRLEN_BOUND (1) == 1); +verify (INT_BITS_STRLEN_BOUND (2620) == 789); + +/* INT_STRLEN_BOUND, INT_BUFSIZE_BOUND. */ +#ifdef INT32_MAX /* POSIX guarantees int32_t; this ports to non-POSIX hosts */ +verify (INT_STRLEN_BOUND (int32_t) == sizeof ("-2147483648") - 1); +verify (INT_BUFSIZE_BOUND (int32_t) == sizeof ("-2147483648")); +#endif +#ifdef INT64_MAX +verify (INT_STRLEN_BOUND (int64_t) == sizeof ("-9223372036854775808") - 1); +verify (INT_BUFSIZE_BOUND (int64_t) == sizeof ("-9223372036854775808")); #endif +/* All the INT_<op>_RANGE_OVERFLOW tests are equally valid as + INT_<op>_OVERFLOW tests, so define a single macro to do both. */ +#define check_binop(op, a, b, min, max, overflow) \ + (INT_##op##_RANGE_OVERFLOW (a, b, min, max) == (overflow) \ + && INT_##op##_OVERFLOW (a, b) == (overflow)) +#define check_unop(op, a, min, max, overflow) \ + (INT_##op##_RANGE_OVERFLOW (a, min, max) == (overflow) \ + && INT_##op##_OVERFLOW (a) == (overflow)) + +/* INT_<op>_RANGE_OVERFLOW, INT_<op>_OVERFLOW. */ +verify (INT_ADD_RANGE_OVERFLOW (INT_MAX, 1, INT_MIN, INT_MAX)); +verify (INT_ADD_OVERFLOW (INT_MAX, 1)); +verify (check_binop (ADD, INT_MAX, 1, INT_MIN, INT_MAX, true)); +verify (check_binop (ADD, INT_MAX, -1, INT_MIN, INT_MAX, false)); +verify (check_binop (ADD, INT_MIN, 1, INT_MIN, INT_MAX, false)); +verify (check_binop (ADD, INT_MIN, -1, INT_MIN, INT_MAX, true)); +verify (check_binop (ADD, UINT_MAX, 1u, 0u, UINT_MAX, true)); +verify (check_binop (ADD, 0u, 1u, 0u, UINT_MAX, false)); + +verify (check_binop (SUBTRACT, INT_MAX, 1, INT_MIN, INT_MAX, false)); +verify (check_binop (SUBTRACT, INT_MAX, -1, INT_MIN, INT_MAX, true)); +verify (check_binop (SUBTRACT, INT_MIN, 1, INT_MIN, INT_MAX, true)); +verify (check_binop (SUBTRACT, INT_MIN, -1, INT_MIN, INT_MAX, false)); +verify (check_binop (SUBTRACT, UINT_MAX, 1u, 0u, UINT_MAX, false)); +verify (check_binop (SUBTRACT, 0u, 1u, 0u, UINT_MAX, true)); + +verify (check_unop (NEGATE, INT_MIN, INT_MIN, INT_MAX, + TYPE_TWOS_COMPLEMENT (int))); +verify (check_unop (NEGATE, 0, INT_MIN, INT_MAX, false)); +verify (check_unop (NEGATE, INT_MAX, INT_MIN, INT_MAX, false)); +verify (check_unop (NEGATE, 0u, 0u, UINT_MAX, false)); +verify (check_unop (NEGATE, 1u, 0u, UINT_MAX, true)); +verify (check_unop (NEGATE, UINT_MAX, 0u, UINT_MAX, true)); + +verify (check_binop (MULTIPLY, INT_MAX, INT_MAX, INT_MIN, INT_MAX, true)); +verify (check_binop (MULTIPLY, INT_MAX, INT_MIN, INT_MIN, INT_MAX, true)); +verify (check_binop (MULTIPLY, INT_MIN, INT_MAX, INT_MIN, INT_MAX, true)); +verify (check_binop (MULTIPLY, INT_MIN, INT_MIN, INT_MIN, INT_MAX, true)); +verify (check_binop (MULTIPLY, -1, INT_MIN, INT_MIN, INT_MAX, + INT_NEGATE_OVERFLOW (INT_MIN))); +verify (check_binop (MULTIPLY, LONG_MIN / INT_MAX, (long int) INT_MAX, + LONG_MIN, LONG_MIN, false)); + +verify (check_binop (DIVIDE, INT_MIN, -1, INT_MIN, INT_MAX, + INT_NEGATE_OVERFLOW (INT_MIN))); +verify (check_binop (DIVIDE, INT_MAX, 1, INT_MIN, INT_MAX, false)); +verify (check_binop (DIVIDE, (unsigned int) INT_MIN, + -1u, 0u, UINT_MAX, false)); + +verify (check_binop (REMAINDER, INT_MIN, -1, INT_MIN, INT_MAX, + INT_NEGATE_OVERFLOW (INT_MIN))); +verify (check_binop (REMAINDER, INT_MAX, 1, INT_MIN, INT_MAX, false)); +verify (check_binop (REMAINDER, (unsigned int) INT_MIN, + -1u, 0u, UINT_MAX, false)); + +verify (check_binop (LEFT_SHIFT, UINT_MAX, 1, 0u, UINT_MAX, true)); +verify (check_binop (LEFT_SHIFT, UINT_MAX / 2 + 1, 1, 0u, UINT_MAX, true)); +verify (check_binop (LEFT_SHIFT, UINT_MAX / 2, 1, 0u, UINT_MAX, false)); + +/* INT_<op>_OVERFLOW with mixed types. */ +#define check_sum(a, b, overflow) \ + verify (INT_ADD_OVERFLOW (a, b) == (overflow)); \ + verify (INT_ADD_OVERFLOW (b, a) == (overflow)) +check_sum (-1, LONG_MIN, true); +check_sum (-1, UINT_MAX, false); +check_sum (-1L, INT_MIN, INT_MIN == LONG_MIN); +check_sum (0u, -1, true); +check_sum (0u, 0, false); +check_sum (0u, 1, false); +check_sum (1, LONG_MAX, true); +check_sum (1, UINT_MAX, true); +check_sum (1L, INT_MAX, INT_MAX == LONG_MAX); +check_sum (1u, INT_MAX, INT_MAX == UINT_MAX); +check_sum (1u, INT_MIN, true); + +verify (! INT_SUBTRACT_OVERFLOW (INT_MAX, 1u)); +verify (! INT_SUBTRACT_OVERFLOW (UINT_MAX, 1)); +verify (! INT_SUBTRACT_OVERFLOW (0u, -1)); +verify (INT_SUBTRACT_OVERFLOW (UINT_MAX, -1)); +verify (INT_SUBTRACT_OVERFLOW (INT_MIN, 1u)); +verify (INT_SUBTRACT_OVERFLOW (-1, 0u)); + +#define check_product(a, b, overflow) \ + verify (INT_MULTIPLY_OVERFLOW (a, b) == (overflow)); \ + verify (INT_MULTIPLY_OVERFLOW (b, a) == (overflow)) + +check_product (-1, 1u, true); +check_product (-1, INT_MIN, INT_NEGATE_OVERFLOW (INT_MIN)); +check_product (-1, UINT_MAX, true); +check_product (-12345, LONG_MAX / -12345 - 1, true); +check_product (-12345, LONG_MAX / -12345, false); +check_product (0, -1, false); +check_product (0, 0, false); +check_product (0, 0u, false); +check_product (0, 1, false); +check_product (0, INT_MAX, false); +check_product (0, INT_MIN, false); +check_product (0, UINT_MAX, false); +check_product (0u, -1, false); +check_product (0u, 0, false); +check_product (0u, 0u, false); +check_product (0u, 1, false); +check_product (0u, INT_MAX, false); +check_product (0u, INT_MIN, false); +check_product (0u, UINT_MAX, false); +check_product (1, INT_MAX, false); +check_product (1, INT_MIN, false); +check_product (1, UINT_MAX, false); +check_product (1u, INT_MIN, true); +check_product (1u, INT_MAX, UINT_MAX < INT_MAX); +check_product (INT_MAX, UINT_MAX, true); +check_product (INT_MAX, ULONG_MAX, true); +check_product (INT_MIN, LONG_MAX / INT_MIN - 1, true); +check_product (INT_MIN, LONG_MAX / INT_MIN, false); +check_product (INT_MIN, UINT_MAX, true); +check_product (INT_MIN, ULONG_MAX, true); + +verify (INT_DIVIDE_OVERFLOW (INT_MIN, -1L) + == (TYPE_TWOS_COMPLEMENT (long int) && INT_MIN == LONG_MIN)); +verify (! INT_DIVIDE_OVERFLOW (INT_MIN, UINT_MAX)); +verify (! INT_DIVIDE_OVERFLOW (INTMAX_MIN, UINTMAX_MAX)); +verify (! INT_DIVIDE_OVERFLOW (INTMAX_MIN, UINT_MAX)); +verify (INT_DIVIDE_OVERFLOW (-11, 10u)); +verify (INT_DIVIDE_OVERFLOW (-10, 10u)); +verify (! INT_DIVIDE_OVERFLOW (-9, 10u)); +verify (INT_DIVIDE_OVERFLOW (11u, -10)); +verify (INT_DIVIDE_OVERFLOW (10u, -10)); +verify (! INT_DIVIDE_OVERFLOW (9u, -10)); + +verify (INT_REMAINDER_OVERFLOW (INT_MIN, -1L) + == (TYPE_TWOS_COMPLEMENT (long int) && INT_MIN == LONG_MIN)); +verify (INT_REMAINDER_OVERFLOW (-1, UINT_MAX)); +verify (INT_REMAINDER_OVERFLOW ((intmax_t) -1, UINTMAX_MAX)); +verify (INT_REMAINDER_OVERFLOW (INTMAX_MIN, UINT_MAX) + == (INTMAX_MAX < UINT_MAX + && - (unsigned int) INTMAX_MIN % UINT_MAX != 0)); +verify (INT_REMAINDER_OVERFLOW (INT_MIN, ULONG_MAX) + == (INT_MIN % ULONG_MAX != 1)); +verify (! INT_REMAINDER_OVERFLOW (1u, -1)); +verify (! INT_REMAINDER_OVERFLOW (37*39u, -39)); +verify (INT_REMAINDER_OVERFLOW (37*39u + 1, -39)); +verify (INT_REMAINDER_OVERFLOW (37*39u - 1, -39)); +verify (! INT_REMAINDER_OVERFLOW (LONG_MAX, -INT_MAX)); + int main (void) { - /* Use VERIFY for tests that must be integer constant expressions, - ASSERT otherwise. */ - - /* TYPE_IS_INTEGER. */ - ASSERT (TYPE_IS_INTEGER (bool)); - ASSERT (TYPE_IS_INTEGER (char)); - ASSERT (TYPE_IS_INTEGER (signed char)); - ASSERT (TYPE_IS_INTEGER (unsigned char)); - ASSERT (TYPE_IS_INTEGER (short int)); - ASSERT (TYPE_IS_INTEGER (unsigned short int)); - ASSERT (TYPE_IS_INTEGER (int)); - ASSERT (TYPE_IS_INTEGER (unsigned int)); - ASSERT (TYPE_IS_INTEGER (long int)); - ASSERT (TYPE_IS_INTEGER (unsigned long int)); - ASSERT (TYPE_IS_INTEGER (intmax_t)); - ASSERT (TYPE_IS_INTEGER (uintmax_t)); - ASSERT (! TYPE_IS_INTEGER (float)); - ASSERT (! TYPE_IS_INTEGER (double)); - ASSERT (! TYPE_IS_INTEGER (long double)); - - /* TYPE_SIGNED. */ - /* VERIFY (! TYPE_SIGNED (bool)); // not guaranteed by gnulib substitute */ - VERIFY (TYPE_SIGNED (signed char)); - VERIFY (! TYPE_SIGNED (unsigned char)); - VERIFY (TYPE_SIGNED (short int)); - VERIFY (! TYPE_SIGNED (unsigned short int)); - VERIFY (TYPE_SIGNED (int)); - VERIFY (! TYPE_SIGNED (unsigned int)); - VERIFY (TYPE_SIGNED (long int)); - VERIFY (! TYPE_SIGNED (unsigned long int)); - VERIFY (TYPE_SIGNED (intmax_t)); - VERIFY (! TYPE_SIGNED (uintmax_t)); - ASSERT (TYPE_SIGNED (float)); - ASSERT (TYPE_SIGNED (double)); - ASSERT (TYPE_SIGNED (long double)); - - /* Integer representation. */ - VERIFY (INT_MIN + INT_MAX < 0 - ? (TYPE_TWOS_COMPLEMENT (int) - && ! TYPE_ONES_COMPLEMENT (int) && ! TYPE_SIGNED_MAGNITUDE (int)) - : (! TYPE_TWOS_COMPLEMENT (int) - && (TYPE_ONES_COMPLEMENT (int) || TYPE_SIGNED_MAGNITUDE (int)))); - - /* TYPE_MINIMUM, TYPE_MAXIMUM. */ - VERIFY (TYPE_MINIMUM (char) == CHAR_MIN); - VERIFY (TYPE_MAXIMUM (char) == CHAR_MAX); - VERIFY (TYPE_MINIMUM (unsigned char) == 0); - VERIFY (TYPE_MAXIMUM (unsigned char) == UCHAR_MAX); - VERIFY (TYPE_MINIMUM (signed char) == SCHAR_MIN); - VERIFY (TYPE_MAXIMUM (signed char) == SCHAR_MAX); - VERIFY (TYPE_MINIMUM (short int) == SHRT_MIN); - VERIFY (TYPE_MAXIMUM (short int) == SHRT_MAX); - VERIFY (TYPE_MINIMUM (unsigned short int) == 0); - VERIFY (TYPE_MAXIMUM (unsigned short int) == USHRT_MAX); - VERIFY (TYPE_MINIMUM (int) == INT_MIN); - VERIFY (TYPE_MAXIMUM (int) == INT_MAX); - VERIFY (TYPE_MINIMUM (unsigned int) == 0); - VERIFY (TYPE_MAXIMUM (unsigned int) == UINT_MAX); - VERIFY (TYPE_MINIMUM (long int) == LONG_MIN); - VERIFY (TYPE_MAXIMUM (long int) == LONG_MAX); - VERIFY (TYPE_MINIMUM (unsigned long int) == 0); - VERIFY (TYPE_MAXIMUM (unsigned long int) == ULONG_MAX); - VERIFY (TYPE_MINIMUM (intmax_t) == INTMAX_MIN); - VERIFY (TYPE_MAXIMUM (intmax_t) == INTMAX_MAX); - VERIFY (TYPE_MINIMUM (uintmax_t) == 0); - VERIFY (TYPE_MAXIMUM (uintmax_t) == UINTMAX_MAX); - - /* INT_BITS_STRLEN_BOUND. */ - VERIFY (INT_BITS_STRLEN_BOUND (1) == 1); - VERIFY (INT_BITS_STRLEN_BOUND (2620) == 789); - - /* INT_STRLEN_BOUND, INT_BUFSIZE_BOUND. */ - #ifdef INT32_MAX /* POSIX guarantees int32_t; this ports to non-POSIX. */ - VERIFY (INT_STRLEN_BOUND (int32_t) == sizeof ("-2147483648") - 1); - VERIFY (INT_BUFSIZE_BOUND (int32_t) == sizeof ("-2147483648")); - #endif - #ifdef INT64_MAX - VERIFY (INT_STRLEN_BOUND (int64_t) == sizeof ("-9223372036854775808") - 1); - VERIFY (INT_BUFSIZE_BOUND (int64_t) == sizeof ("-9223372036854775808")); - #endif - - /* All the INT_<op>_RANGE_OVERFLOW tests are equally valid as - INT_<op>_OVERFLOW tests, so define a single macro to do both. */ - #define CHECK_BINOP(op, a, b, min, max, overflow) \ - (INT_##op##_RANGE_OVERFLOW (a, b, min, max) == (overflow) \ - && INT_##op##_OVERFLOW (a, b) == (overflow)) - #define CHECK_UNOP(op, a, min, max, overflow) \ - (INT_##op##_RANGE_OVERFLOW (a, min, max) == (overflow) \ - && INT_##op##_OVERFLOW (a) == (overflow)) - - /* INT_<op>_RANGE_OVERFLOW, INT_<op>_OVERFLOW. */ - VERIFY (INT_ADD_RANGE_OVERFLOW (INT_MAX, 1, INT_MIN, INT_MAX)); - VERIFY (INT_ADD_OVERFLOW (INT_MAX, 1)); - VERIFY (CHECK_BINOP (ADD, INT_MAX, 1, INT_MIN, INT_MAX, true)); - VERIFY (CHECK_BINOP (ADD, INT_MAX, -1, INT_MIN, INT_MAX, false)); - VERIFY (CHECK_BINOP (ADD, INT_MIN, 1, INT_MIN, INT_MAX, false)); - VERIFY (CHECK_BINOP (ADD, INT_MIN, -1, INT_MIN, INT_MAX, true)); - VERIFY (CHECK_BINOP (ADD, UINT_MAX, 1u, 0u, UINT_MAX, true)); - VERIFY (CHECK_BINOP (ADD, 0u, 1u, 0u, UINT_MAX, false)); - - VERIFY (CHECK_BINOP (SUBTRACT, INT_MAX, 1, INT_MIN, INT_MAX, false)); - VERIFY (CHECK_BINOP (SUBTRACT, INT_MAX, -1, INT_MIN, INT_MAX, true)); - VERIFY (CHECK_BINOP (SUBTRACT, INT_MIN, 1, INT_MIN, INT_MAX, true)); - VERIFY (CHECK_BINOP (SUBTRACT, INT_MIN, -1, INT_MIN, INT_MAX, false)); - VERIFY (CHECK_BINOP (SUBTRACT, UINT_MAX, 1u, 0u, UINT_MAX, false)); - VERIFY (CHECK_BINOP (SUBTRACT, 0u, 1u, 0u, UINT_MAX, true)); - - VERIFY (CHECK_UNOP (NEGATE, INT_MIN, INT_MIN, INT_MAX, - TYPE_TWOS_COMPLEMENT (int))); - VERIFY (CHECK_UNOP (NEGATE, 0, INT_MIN, INT_MAX, false)); - VERIFY (CHECK_UNOP (NEGATE, INT_MAX, INT_MIN, INT_MAX, false)); - VERIFY (CHECK_UNOP (NEGATE, 0u, 0u, UINT_MAX, false)); - VERIFY (CHECK_UNOP (NEGATE, 1u, 0u, UINT_MAX, true)); - VERIFY (CHECK_UNOP (NEGATE, UINT_MAX, 0u, UINT_MAX, true)); - - VERIFY (CHECK_BINOP (MULTIPLY, INT_MAX, INT_MAX, INT_MIN, INT_MAX, true)); - VERIFY (CHECK_BINOP (MULTIPLY, INT_MAX, INT_MIN, INT_MIN, INT_MAX, true)); - VERIFY (CHECK_BINOP (MULTIPLY, INT_MIN, INT_MAX, INT_MIN, INT_MAX, true)); - VERIFY (CHECK_BINOP (MULTIPLY, INT_MIN, INT_MIN, INT_MIN, INT_MAX, true)); - VERIFY (CHECK_BINOP (MULTIPLY, -1, INT_MIN, INT_MIN, INT_MAX, - INT_NEGATE_OVERFLOW (INT_MIN))); - VERIFY (CHECK_BINOP (MULTIPLY, LONG_MIN / INT_MAX, (long int) INT_MAX, - LONG_MIN, LONG_MIN, false)); - - VERIFY (CHECK_BINOP (DIVIDE, INT_MIN, -1, INT_MIN, INT_MAX, - INT_NEGATE_OVERFLOW (INT_MIN))); - VERIFY (CHECK_BINOP (DIVIDE, INT_MAX, 1, INT_MIN, INT_MAX, false)); - VERIFY (CHECK_BINOP (DIVIDE, (unsigned int) INT_MIN, - -1u, 0u, UINT_MAX, false)); - - VERIFY (CHECK_BINOP (REMAINDER, INT_MIN, -1, INT_MIN, INT_MAX, - INT_NEGATE_OVERFLOW (INT_MIN))); - VERIFY (CHECK_BINOP (REMAINDER, INT_MAX, 1, INT_MIN, INT_MAX, false)); - VERIFY (CHECK_BINOP (REMAINDER, (unsigned int) INT_MIN, - -1u, 0u, UINT_MAX, false)); - - VERIFY (CHECK_BINOP (LEFT_SHIFT, UINT_MAX, 1, 0u, UINT_MAX, true)); - VERIFY (CHECK_BINOP (LEFT_SHIFT, UINT_MAX / 2 + 1, 1, 0u, UINT_MAX, true)); - VERIFY (CHECK_BINOP (LEFT_SHIFT, UINT_MAX / 2, 1, 0u, UINT_MAX, false)); - - /* INT_<op>_OVERFLOW with mixed types. */ - #define CHECK_SUM(a, b, overflow) \ - VERIFY (INT_ADD_OVERFLOW (a, b) == (overflow)); \ - VERIFY (INT_ADD_OVERFLOW (b, a) == (overflow)) - CHECK_SUM (-1, LONG_MIN, true); - CHECK_SUM (-1, UINT_MAX, false); - CHECK_SUM (-1L, INT_MIN, INT_MIN == LONG_MIN); - CHECK_SUM (0u, -1, true); - CHECK_SUM (0u, 0, false); - CHECK_SUM (0u, 1, false); - CHECK_SUM (1, LONG_MAX, true); - CHECK_SUM (1, UINT_MAX, true); - CHECK_SUM (1L, INT_MAX, INT_MAX == LONG_MAX); - CHECK_SUM (1u, INT_MAX, INT_MAX == UINT_MAX); - CHECK_SUM (1u, INT_MIN, true); - - VERIFY (! INT_SUBTRACT_OVERFLOW (INT_MAX, 1u)); - VERIFY (! INT_SUBTRACT_OVERFLOW (UINT_MAX, 1)); - VERIFY (! INT_SUBTRACT_OVERFLOW (0u, -1)); - VERIFY (INT_SUBTRACT_OVERFLOW (UINT_MAX, -1)); - VERIFY (INT_SUBTRACT_OVERFLOW (INT_MIN, 1u)); - VERIFY (INT_SUBTRACT_OVERFLOW (-1, 0u)); - - #define CHECK_PRODUCT(a, b, overflow) \ - VERIFY (INT_MULTIPLY_OVERFLOW (a, b) == (overflow)); \ - VERIFY (INT_MULTIPLY_OVERFLOW (b, a) == (overflow)) - - CHECK_PRODUCT (-1, 1u, true); - CHECK_PRODUCT (-1, INT_MIN, INT_NEGATE_OVERFLOW (INT_MIN)); - CHECK_PRODUCT (-1, UINT_MAX, true); - CHECK_PRODUCT (-12345, LONG_MAX / -12345 - 1, true); - CHECK_PRODUCT (-12345, LONG_MAX / -12345, false); - CHECK_PRODUCT (0, -1, false); - CHECK_PRODUCT (0, 0, false); - CHECK_PRODUCT (0, 0u, false); - CHECK_PRODUCT (0, 1, false); - CHECK_PRODUCT (0, INT_MAX, false); - CHECK_PRODUCT (0, INT_MIN, false); - CHECK_PRODUCT (0, UINT_MAX, false); - CHECK_PRODUCT (0u, -1, false); - CHECK_PRODUCT (0u, 0, false); - CHECK_PRODUCT (0u, 0u, false); - CHECK_PRODUCT (0u, 1, false); - CHECK_PRODUCT (0u, INT_MAX, false); - CHECK_PRODUCT (0u, INT_MIN, false); - CHECK_PRODUCT (0u, UINT_MAX, false); - CHECK_PRODUCT (1, INT_MAX, false); - CHECK_PRODUCT (1, INT_MIN, false); - CHECK_PRODUCT (1, UINT_MAX, false); - CHECK_PRODUCT (1u, INT_MIN, true); - CHECK_PRODUCT (1u, INT_MAX, UINT_MAX < INT_MAX); - CHECK_PRODUCT (INT_MAX, UINT_MAX, true); - CHECK_PRODUCT (INT_MAX, ULONG_MAX, true); - CHECK_PRODUCT (INT_MIN, LONG_MAX / INT_MIN - 1, true); - CHECK_PRODUCT (INT_MIN, LONG_MAX / INT_MIN, false); - CHECK_PRODUCT (INT_MIN, UINT_MAX, true); - CHECK_PRODUCT (INT_MIN, ULONG_MAX, true); - - VERIFY (INT_DIVIDE_OVERFLOW (INT_MIN, -1L) - == (TYPE_TWOS_COMPLEMENT (long int) && INT_MIN == LONG_MIN)); - VERIFY (! INT_DIVIDE_OVERFLOW (INT_MIN, UINT_MAX)); - VERIFY (! INT_DIVIDE_OVERFLOW (INTMAX_MIN, UINTMAX_MAX)); - VERIFY (! INT_DIVIDE_OVERFLOW (INTMAX_MIN, UINT_MAX)); - VERIFY (INT_DIVIDE_OVERFLOW (-11, 10u)); - VERIFY (INT_DIVIDE_OVERFLOW (-10, 10u)); - VERIFY (! INT_DIVIDE_OVERFLOW (-9, 10u)); - VERIFY (INT_DIVIDE_OVERFLOW (11u, -10)); - VERIFY (INT_DIVIDE_OVERFLOW (10u, -10)); - VERIFY (! INT_DIVIDE_OVERFLOW (9u, -10)); - - VERIFY (INT_REMAINDER_OVERFLOW (INT_MIN, -1L) - == (TYPE_TWOS_COMPLEMENT (long int) && INT_MIN == LONG_MIN)); - VERIFY (INT_REMAINDER_OVERFLOW (-1, UINT_MAX)); - VERIFY (INT_REMAINDER_OVERFLOW ((intmax_t) -1, UINTMAX_MAX)); - VERIFY (INT_REMAINDER_OVERFLOW (INTMAX_MIN, UINT_MAX) - == (INTMAX_MAX < UINT_MAX - && - (unsigned int) INTMAX_MIN % UINT_MAX != 0)); - VERIFY (INT_REMAINDER_OVERFLOW (INT_MIN, ULONG_MAX) - == (INT_MIN % ULONG_MAX != 1)); - VERIFY (! INT_REMAINDER_OVERFLOW (1u, -1)); - VERIFY (! INT_REMAINDER_OVERFLOW (37*39u, -39)); - VERIFY (INT_REMAINDER_OVERFLOW (37*39u + 1, -39)); - VERIFY (INT_REMAINDER_OVERFLOW (37*39u - 1, -39)); - VERIFY (! INT_REMAINDER_OVERFLOW (LONG_MAX, -INT_MAX)); - return 0; } diff --git a/gl/tests/test-lock.c b/gl/tests/test-lock.c deleted file mode 100644 index 04ce0767ff..0000000000 --- a/gl/tests/test-lock.c +++ /dev/null @@ -1,601 +0,0 @@ -/* Test of locking in multithreaded situations. - Copyright (C) 2005, 2008-2011 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -/* Written by Bruno Haible <bruno@clisp.org>, 2005. */ - -#include <config.h> - -#if USE_POSIX_THREADS || USE_SOLARIS_THREADS || USE_PTH_THREADS || USE_WIN32_THREADS - -#if USE_POSIX_THREADS -# define TEST_POSIX_THREADS 1 -#endif -#if USE_SOLARIS_THREADS -# define TEST_SOLARIS_THREADS 1 -#endif -#if USE_PTH_THREADS -# define TEST_PTH_THREADS 1 -#endif -#if USE_WIN32_THREADS -# define TEST_WIN32_THREADS 1 -#endif - -/* Whether to enable locking. - Uncomment this to get a test program without locking, to verify that - it crashes. */ -#define ENABLE_LOCKING 1 - -/* Which tests to perform. - Uncomment some of these, to verify that all tests crash if no locking - is enabled. */ -#define DO_TEST_LOCK 1 -#define DO_TEST_RWLOCK 1 -#define DO_TEST_RECURSIVE_LOCK 1 -#define DO_TEST_ONCE 1 - -/* Whether to help the scheduler through explicit yield(). - Uncomment this to see if the operating system has a fair scheduler. */ -#define EXPLICIT_YIELD 1 - -/* Whether to print debugging messages. */ -#define ENABLE_DEBUGGING 0 - -/* Number of simultaneous threads. */ -#define THREAD_COUNT 10 - -/* Number of operations performed in each thread. - This is quite high, because with a smaller count, say 5000, we often get - an "OK" result even without ENABLE_LOCKING (on Linux/x86). */ -#define REPEAT_COUNT 50000 - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#if !ENABLE_LOCKING -# undef USE_POSIX_THREADS -# undef USE_SOLARIS_THREADS -# undef USE_PTH_THREADS -# undef USE_WIN32_THREADS -#endif -#include "glthread/lock.h" - -#if !ENABLE_LOCKING -# if TEST_POSIX_THREADS -# define USE_POSIX_THREADS 1 -# endif -# if TEST_SOLARIS_THREADS -# define USE_SOLARIS_THREADS 1 -# endif -# if TEST_PTH_THREADS -# define USE_PTH_THREADS 1 -# endif -# if TEST_WIN32_THREADS -# define USE_WIN32_THREADS 1 -# endif -#endif - -#include "glthread/thread.h" -#include "glthread/yield.h" - -#if ENABLE_DEBUGGING -# define dbgprintf printf -#else -# define dbgprintf if (0) printf -#endif - -#if EXPLICIT_YIELD -# define yield() gl_thread_yield () -#else -# define yield() -#endif - -#define ACCOUNT_COUNT 4 - -static int account[ACCOUNT_COUNT]; - -static int -random_account (void) -{ - return ((unsigned int) rand () >> 3) % ACCOUNT_COUNT; -} - -static void -check_accounts (void) -{ - int i, sum; - - sum = 0; - for (i = 0; i < ACCOUNT_COUNT; i++) - sum += account[i]; - if (sum != ACCOUNT_COUNT * 1000) - abort (); -} - - -/* ------------------- Test normal (non-recursive) locks ------------------- */ - -/* Test normal locks by having several bank accounts and several threads - which shuffle around money between the accounts and another thread - checking that all the money is still there. */ - -gl_lock_define_initialized(static, my_lock) - -static void * -lock_mutator_thread (void *arg) -{ - int repeat; - - for (repeat = REPEAT_COUNT; repeat > 0; repeat--) - { - int i1, i2, value; - - dbgprintf ("Mutator %p before lock\n", gl_thread_self ()); - gl_lock_lock (my_lock); - dbgprintf ("Mutator %p after lock\n", gl_thread_self ()); - - i1 = random_account (); - i2 = random_account (); - value = ((unsigned int) rand () >> 3) % 10; - account[i1] += value; - account[i2] -= value; - - dbgprintf ("Mutator %p before unlock\n", gl_thread_self ()); - gl_lock_unlock (my_lock); - dbgprintf ("Mutator %p after unlock\n", gl_thread_self ()); - - dbgprintf ("Mutator %p before check lock\n", gl_thread_self ()); - gl_lock_lock (my_lock); - check_accounts (); - gl_lock_unlock (my_lock); - dbgprintf ("Mutator %p after check unlock\n", gl_thread_self ()); - - yield (); - } - - dbgprintf ("Mutator %p dying.\n", gl_thread_self ()); - return NULL; -} - -static volatile int lock_checker_done; - -static void * -lock_checker_thread (void *arg) -{ - while (!lock_checker_done) - { - dbgprintf ("Checker %p before check lock\n", gl_thread_self ()); - gl_lock_lock (my_lock); - check_accounts (); - gl_lock_unlock (my_lock); - dbgprintf ("Checker %p after check unlock\n", gl_thread_self ()); - - yield (); - } - - dbgprintf ("Checker %p dying.\n", gl_thread_self ()); - return NULL; -} - -static void -test_lock (void) -{ - int i; - gl_thread_t checkerthread; - gl_thread_t threads[THREAD_COUNT]; - - /* Initialization. */ - for (i = 0; i < ACCOUNT_COUNT; i++) - account[i] = 1000; - lock_checker_done = 0; - - /* Spawn the threads. */ - checkerthread = gl_thread_create (lock_checker_thread, NULL); - for (i = 0; i < THREAD_COUNT; i++) - threads[i] = gl_thread_create (lock_mutator_thread, NULL); - - /* Wait for the threads to terminate. */ - for (i = 0; i < THREAD_COUNT; i++) - gl_thread_join (threads[i], NULL); - lock_checker_done = 1; - gl_thread_join (checkerthread, NULL); - check_accounts (); -} - - -/* ----------------- Test read-write (non-recursive) locks ----------------- */ - -/* Test read-write locks by having several bank accounts and several threads - which shuffle around money between the accounts and several other threads - that check that all the money is still there. */ - -gl_rwlock_define_initialized(static, my_rwlock) - -static void * -rwlock_mutator_thread (void *arg) -{ - int repeat; - - for (repeat = REPEAT_COUNT; repeat > 0; repeat--) - { - int i1, i2, value; - - dbgprintf ("Mutator %p before wrlock\n", gl_thread_self ()); - gl_rwlock_wrlock (my_rwlock); - dbgprintf ("Mutator %p after wrlock\n", gl_thread_self ()); - - i1 = random_account (); - i2 = random_account (); - value = ((unsigned int) rand () >> 3) % 10; - account[i1] += value; - account[i2] -= value; - - dbgprintf ("Mutator %p before unlock\n", gl_thread_self ()); - gl_rwlock_unlock (my_rwlock); - dbgprintf ("Mutator %p after unlock\n", gl_thread_self ()); - - yield (); - } - - dbgprintf ("Mutator %p dying.\n", gl_thread_self ()); - return NULL; -} - -static volatile int rwlock_checker_done; - -static void * -rwlock_checker_thread (void *arg) -{ - while (!rwlock_checker_done) - { - dbgprintf ("Checker %p before check rdlock\n", gl_thread_self ()); - gl_rwlock_rdlock (my_rwlock); - check_accounts (); - gl_rwlock_unlock (my_rwlock); - dbgprintf ("Checker %p after check unlock\n", gl_thread_self ()); - - yield (); - } - - dbgprintf ("Checker %p dying.\n", gl_thread_self ()); - return NULL; -} - -static void -test_rwlock (void) -{ - int i; - gl_thread_t checkerthreads[THREAD_COUNT]; - gl_thread_t threads[THREAD_COUNT]; - - /* Initialization. */ - for (i = 0; i < ACCOUNT_COUNT; i++) - account[i] = 1000; - rwlock_checker_done = 0; - - /* Spawn the threads. */ - for (i = 0; i < THREAD_COUNT; i++) - checkerthreads[i] = gl_thread_create (rwlock_checker_thread, NULL); - for (i = 0; i < THREAD_COUNT; i++) - threads[i] = gl_thread_create (rwlock_mutator_thread, NULL); - - /* Wait for the threads to terminate. */ - for (i = 0; i < THREAD_COUNT; i++) - gl_thread_join (threads[i], NULL); - rwlock_checker_done = 1; - for (i = 0; i < THREAD_COUNT; i++) - gl_thread_join (checkerthreads[i], NULL); - check_accounts (); -} - - -/* -------------------------- Test recursive locks -------------------------- */ - -/* Test recursive locks by having several bank accounts and several threads - which shuffle around money between the accounts (recursively) and another - thread checking that all the money is still there. */ - -gl_recursive_lock_define_initialized(static, my_reclock) - -static void -recshuffle (void) -{ - int i1, i2, value; - - dbgprintf ("Mutator %p before lock\n", gl_thread_self ()); - gl_recursive_lock_lock (my_reclock); - dbgprintf ("Mutator %p after lock\n", gl_thread_self ()); - - i1 = random_account (); - i2 = random_account (); - value = ((unsigned int) rand () >> 3) % 10; - account[i1] += value; - account[i2] -= value; - - /* Recursive with probability 0.5. */ - if (((unsigned int) rand () >> 3) % 2) - recshuffle (); - - dbgprintf ("Mutator %p before unlock\n", gl_thread_self ()); - gl_recursive_lock_unlock (my_reclock); - dbgprintf ("Mutator %p after unlock\n", gl_thread_self ()); -} - -static void * -reclock_mutator_thread (void *arg) -{ - int repeat; - - for (repeat = REPEAT_COUNT; repeat > 0; repeat--) - { - recshuffle (); - - dbgprintf ("Mutator %p before check lock\n", gl_thread_self ()); - gl_recursive_lock_lock (my_reclock); - check_accounts (); - gl_recursive_lock_unlock (my_reclock); - dbgprintf ("Mutator %p after check unlock\n", gl_thread_self ()); - - yield (); - } - - dbgprintf ("Mutator %p dying.\n", gl_thread_self ()); - return NULL; -} - -static volatile int reclock_checker_done; - -static void * -reclock_checker_thread (void *arg) -{ - while (!reclock_checker_done) - { - dbgprintf ("Checker %p before check lock\n", gl_thread_self ()); - gl_recursive_lock_lock (my_reclock); - check_accounts (); - gl_recursive_lock_unlock (my_reclock); - dbgprintf ("Checker %p after check unlock\n", gl_thread_self ()); - - yield (); - } - - dbgprintf ("Checker %p dying.\n", gl_thread_self ()); - return NULL; -} - -static void -test_recursive_lock (void) -{ - int i; - gl_thread_t checkerthread; - gl_thread_t threads[THREAD_COUNT]; - - /* Initialization. */ - for (i = 0; i < ACCOUNT_COUNT; i++) - account[i] = 1000; - reclock_checker_done = 0; - - /* Spawn the threads. */ - checkerthread = gl_thread_create (reclock_checker_thread, NULL); - for (i = 0; i < THREAD_COUNT; i++) - threads[i] = gl_thread_create (reclock_mutator_thread, NULL); - - /* Wait for the threads to terminate. */ - for (i = 0; i < THREAD_COUNT; i++) - gl_thread_join (threads[i], NULL); - reclock_checker_done = 1; - gl_thread_join (checkerthread, NULL); - check_accounts (); -} - - -/* ------------------------ Test once-only execution ------------------------ */ - -/* Test once-only execution by having several threads attempt to grab a - once-only task simultaneously (triggered by releasing a read-write lock). */ - -gl_once_define(static, fresh_once) -static int ready[THREAD_COUNT]; -static gl_lock_t ready_lock[THREAD_COUNT]; -#if ENABLE_LOCKING -static gl_rwlock_t fire_signal[REPEAT_COUNT]; -#else -static volatile int fire_signal_state; -#endif -static gl_once_t once_control; -static int performed; -gl_lock_define_initialized(static, performed_lock) - -static void -once_execute (void) -{ - gl_lock_lock (performed_lock); - performed++; - gl_lock_unlock (performed_lock); -} - -static void * -once_contender_thread (void *arg) -{ - int id = (int) (long) arg; - int repeat; - - for (repeat = 0; repeat <= REPEAT_COUNT; repeat++) - { - /* Tell the main thread that we're ready. */ - gl_lock_lock (ready_lock[id]); - ready[id] = 1; - gl_lock_unlock (ready_lock[id]); - - if (repeat == REPEAT_COUNT) - break; - - dbgprintf ("Contender %p waiting for signal for round %d\n", - gl_thread_self (), repeat); -#if ENABLE_LOCKING - /* Wait for the signal to go. */ - gl_rwlock_rdlock (fire_signal[repeat]); - /* And don't hinder the others (if the scheduler is unfair). */ - gl_rwlock_unlock (fire_signal[repeat]); -#else - /* Wait for the signal to go. */ - while (fire_signal_state <= repeat) - yield (); -#endif - dbgprintf ("Contender %p got the signal for round %d\n", - gl_thread_self (), repeat); - - /* Contend for execution. */ - gl_once (once_control, once_execute); - } - - return NULL; -} - -static void -test_once (void) -{ - int i, repeat; - gl_thread_t threads[THREAD_COUNT]; - - /* Initialize all variables. */ - for (i = 0; i < THREAD_COUNT; i++) - { - ready[i] = 0; - gl_lock_init (ready_lock[i]); - } -#if ENABLE_LOCKING - for (i = 0; i < REPEAT_COUNT; i++) - gl_rwlock_init (fire_signal[i]); -#else - fire_signal_state = 0; -#endif - - /* Block all fire_signals. */ - for (i = REPEAT_COUNT-1; i >= 0; i--) - gl_rwlock_wrlock (fire_signal[i]); - - /* Spawn the threads. */ - for (i = 0; i < THREAD_COUNT; i++) - threads[i] = gl_thread_create (once_contender_thread, (void *) (long) i); - - for (repeat = 0; repeat <= REPEAT_COUNT; repeat++) - { - /* Wait until every thread is ready. */ - dbgprintf ("Main thread before synchonizing for round %d\n", repeat); - for (;;) - { - int ready_count = 0; - for (i = 0; i < THREAD_COUNT; i++) - { - gl_lock_lock (ready_lock[i]); - ready_count += ready[i]; - gl_lock_unlock (ready_lock[i]); - } - if (ready_count == THREAD_COUNT) - break; - yield (); - } - dbgprintf ("Main thread after synchonizing for round %d\n", repeat); - - if (repeat > 0) - { - /* Check that exactly one thread executed the once_execute() - function. */ - if (performed != 1) - abort (); - } - - if (repeat == REPEAT_COUNT) - break; - - /* Preparation for the next round: Initialize once_control. */ - memcpy (&once_control, &fresh_once, sizeof (gl_once_t)); - - /* Preparation for the next round: Reset the performed counter. */ - performed = 0; - - /* Preparation for the next round: Reset the ready flags. */ - for (i = 0; i < THREAD_COUNT; i++) - { - gl_lock_lock (ready_lock[i]); - ready[i] = 0; - gl_lock_unlock (ready_lock[i]); - } - - /* Signal all threads simultaneously. */ - dbgprintf ("Main thread giving signal for round %d\n", repeat); -#if ENABLE_LOCKING - gl_rwlock_unlock (fire_signal[repeat]); -#else - fire_signal_state = repeat + 1; -#endif - } - - /* Wait for the threads to terminate. */ - for (i = 0; i < THREAD_COUNT; i++) - gl_thread_join (threads[i], NULL); -} - - -/* -------------------------------------------------------------------------- */ - -int -main () -{ -#if TEST_PTH_THREADS - if (!pth_init ()) - abort (); -#endif - -#if DO_TEST_LOCK - printf ("Starting test_lock ..."); fflush (stdout); - test_lock (); - printf (" OK\n"); fflush (stdout); -#endif -#if DO_TEST_RWLOCK - printf ("Starting test_rwlock ..."); fflush (stdout); - test_rwlock (); - printf (" OK\n"); fflush (stdout); -#endif -#if DO_TEST_RECURSIVE_LOCK - printf ("Starting test_recursive_lock ..."); fflush (stdout); - test_recursive_lock (); - printf (" OK\n"); fflush (stdout); -#endif -#if DO_TEST_ONCE - printf ("Starting test_once ..."); fflush (stdout); - test_once (); - printf (" OK\n"); fflush (stdout); -#endif - - return 0; -} - -#else - -/* No multithreading available. */ - -#include <stdio.h> - -int -main () -{ - fputs ("Skipping test: multithreading not enabled\n", stderr); - return 77; -} - -#endif diff --git a/gl/tests/test-strerror.c b/gl/tests/test-strerror.c index 03637d7850..66dbe823d1 100644 --- a/gl/tests/test-strerror.c +++ b/gl/tests/test-strerror.c @@ -33,43 +33,25 @@ main (void) { char *str; - errno = 0; str = strerror (EACCES); ASSERT (str); ASSERT (*str); - ASSERT (errno == 0); - errno = 0; str = strerror (ETIMEDOUT); ASSERT (str); ASSERT (*str); - ASSERT (errno == 0); - errno = 0; str = strerror (EOVERFLOW); ASSERT (str); ASSERT (*str); - ASSERT (errno == 0); - /* POSIX requires strerror (0) to succeed. Reject use of "Unknown - error", but allow "Success", "No error", or even Solaris' "Error - 0" which are distinct patterns from true out-of-range strings. - http://austingroupbugs.net/view.php?id=382 */ - errno = 0; str = strerror (0); ASSERT (str); ASSERT (*str); - ASSERT (errno == 0); - ASSERT (strstr (str, "nknown") == NULL); - /* POSIX requires strerror to produce a non-NULL result for all - inputs; as an extension, we also guarantee a non-empty reseult. - Reporting EINVAL is optional. */ - errno = 0; str = strerror (-3); ASSERT (str); ASSERT (*str); - ASSERT (errno == 0 || errno == EINVAL); return 0; } diff --git a/gl/tests/test-strerror_r.c b/gl/tests/test-strerror_r.c deleted file mode 100644 index 48287678bd..0000000000 --- a/gl/tests/test-strerror_r.c +++ /dev/null @@ -1,112 +0,0 @@ -/* Test of strerror_r() function. - Copyright (C) 2007-2011 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include <config.h> - -#include <string.h> - -#include "signature.h" -SIGNATURE_CHECK (strerror_r, int, (int, char *, size_t)); - -#include <errno.h> - -#include "macros.h" - -int -main (void) -{ - char buf[100]; - int ret; - - /* Test results with valid errnum and enough room. */ - - errno = 0; - buf[0] = '\0'; - ASSERT (strerror_r (EACCES, buf, sizeof (buf)) == 0); - ASSERT (buf[0] != '\0'); - ASSERT (errno == 0); - - errno = 0; - buf[0] = '\0'; - ASSERT (strerror_r (ETIMEDOUT, buf, sizeof (buf)) == 0); - ASSERT (buf[0] != '\0'); - ASSERT (errno == 0); - - errno = 0; - buf[0] = '\0'; - ASSERT (strerror_r (EOVERFLOW, buf, sizeof (buf)) == 0); - ASSERT (buf[0] != '\0'); - ASSERT (errno == 0); - - /* POSIX requires strerror (0) to succeed. Reject use of "Unknown - error", but allow "Success", "No error", or even Solaris' "Error - 0" which are distinct patterns from true out-of-range strings. - http://austingroupbugs.net/view.php?id=382 */ - errno = 0; - buf[0] = '\0'; - ret = strerror_r (0, buf, sizeof (buf)); - ASSERT (ret == 0); - ASSERT (buf[0]); - ASSERT (errno == 0); - ASSERT (strstr (buf, "nknown") == NULL); - - /* Test results with out-of-range errnum and enough room. */ - - errno = 0; - buf[0] = '^'; - ret = strerror_r (-3, buf, sizeof (buf)); - ASSERT (ret == 0 || ret == EINVAL); - if (ret == 0) - ASSERT (buf[0] != '^'); - ASSERT (errno == 0); - - /* Test results with a too small buffer. */ - - ASSERT (strerror_r (EACCES, buf, sizeof (buf)) == 0); - { - size_t len = strlen (buf); - size_t i; - - for (i = 0; i <= len; i++) - { - strcpy (buf, "BADFACE"); - errno = 0; - ret = strerror_r (EACCES, buf, i); - ASSERT (errno == 0); - if (ret == 0) - { - /* Truncated result. POSIX allows this, and it actually - happens on AIX 6.1 and Cygwin. */ - ASSERT ((strcmp (buf, "BADFACE") == 0) == (i == 0)); - } - else - { - /* Failure. */ - ASSERT (ret == ERANGE); - /* buf is clobbered nevertheless, on FreeBSD and MacOS X. */ - } - } - - strcpy (buf, "BADFACE"); - errno = 0; - ret = strerror_r (EACCES, buf, len + 1); - ASSERT (ret == 0); - ASSERT (errno == 0); - } - - return 0; -} |