]> granicus.if.org Git - postgresql/commitdiff
Improve thread test program. Test only functions that need testing.
authorBruce Momjian <bruce@momjian.us>
Fri, 23 Apr 2004 20:35:50 +0000 (20:35 +0000)
committerBruce Momjian <bruce@momjian.us>
Fri, 23 Apr 2004 20:35:50 +0000 (20:35 +0000)
src/tools/thread/Makefile
src/tools/thread/thread_test.c

index 3334d41e248ea0849f8c43b4fa478378a32be566..22d5d09f68487b0757752485a6274f8d805bf8fb 100644 (file)
@@ -4,7 +4,7 @@
 #
 # Copyright (C) 2003 by PostgreSQL Global Development Team
 #
-# $PostgreSQL: pgsql/src/tools/thread/Makefile,v 1.4 2004/04/23 18:15:55 momjian Exp $
+# $PostgreSQL: pgsql/src/tools/thread/Makefile,v 1.5 2004/04/23 20:35:50 momjian Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -12,13 +12,6 @@ subdir = tools/thread
 top_builddir = ../../..
 include $(top_builddir)/src/Makefile.global
 
-ifeq ($(THREAD_SUPPORT), no)
-$(error Your platform does not support threads)
-endif
-ifeq ($(THREAD_SUPPORT), )
-$(error You have not configured your template/$$port file.  See the README)
-endif
-
 override CFLAGS += $(PTHREAD_CFLAGS)
 
 LDFLAGS += $(PTHREAD_LIBS)
index d866f21dbd1cc86518694779fd23e7be574f1969..0edf55226b9c591c6522d21c89661f3a6f00aab3 100644 (file)
@@ -1,12 +1,12 @@
 /*-------------------------------------------------------------------------
  *
  * test_thread_funcs.c
- *      libc thread test program
+ *             libc thread test program
  *
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *     $PostgreSQL: pgsql/src/tools/thread/thread_test.c,v 1.20 2004/04/23 18:15:55 momjian Exp $
+ *     $PostgreSQL: pgsql/src/tools/thread/thread_test.c,v 1.21 2004/04/23 20:35:50 momjian Exp $
  *
  *     This program tests to see if your standard libc functions use
  *     pthread_setspecific()/pthread_getspecific() to be thread-safe.
 
 #include "postgres.h"
 
-void func_call_1(void);
-void func_call_2(void);
+void           func_call_1(void);
+void           func_call_2(void);
 
-char myhostname[MAXHOSTNAMELEN];
-
-volatile int errno1_set = 0;
-volatile int errno2_set = 0;
+pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 volatile int thread1_done = 0;
 volatile int thread2_done = 0;
 
-char *strerror_p1;
-char *strerror_p2;
+volatile int errno1_set = 0;
+volatile int errno2_set = 0;
 
+#ifndef HAVE_STRERROR_R
+char      *strerror_p1;
+char      *strerror_p2;
+bool           strerror_threadsafe = false;
+#endif
+
+#ifndef HAVE_GETPWUID_R
 struct passwd *passwd_p1;
 struct passwd *passwd_p2;
+bool           getpwuid_threadsafe = false;
+#endif
 
+#if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R)
 struct hostent *hostent_p1;
 struct hostent *hostent_p2;
+char           myhostname[MAXHOSTNAMELEN];
+bool           gethostbyname_threadsafe = false;
+#endif
 
-bool gethostbyname_threadsafe = false;
-bool getpwuid_threadsafe = false;
-bool strerror_threadsafe = false;
-bool platform_is_threadsafe = true;
-
-pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
+bool           platform_is_threadsafe = true;
 
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
 {
-       pthread_t               thread1,
-                                       thread2;
+       pthread_t       thread1,
+                               thread2;
 
        if (argc > 1)
        {
-                       fprintf(stderr, "Usage: %s\n", argv[0]);
-                       return 1;
+               fprintf(stderr, "Usage: %s\n", argv[0]);
+               return 1;
        }
 
+#if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R)
        if (gethostname(myhostname, MAXHOSTNAMELEN) != 0)
        {
-                       fprintf(stderr, "can not get local hostname, exiting\n");
-                       exit(1);
+               fprintf(stderr, "can not get local hostname, exiting\n");
+               exit(1);
        }
-
-       printf("\
-Make sure you have added any needed 'PTHREAD_CFLAGS' and 'PTHREAD_LIBS'\n\
-defines to your template/$port file before compiling this program.\n\n"
-);
+#endif
 
        /* Hold lock until we are ready for the child threads to exit. */
-       pthread_mutex_lock(&init_mutex);        
-           
-       pthread_create(&thread1, NULL, (void * (*)(void *)) func_call_1, NULL);
-       pthread_create(&thread2, NULL, (void * (*)(void *)) func_call_2, NULL);
+       pthread_mutex_lock(&init_mutex);
+
+       pthread_create(&thread1, NULL, (void *(*) (void *)) func_call_1, NULL);
+       pthread_create(&thread2, NULL, (void *(*) (void *)) func_call_2, NULL);
 
        while (thread1_done == 0 || thread2_done == 0)
-               sched_yield();  /* if this is a portability problem, remove it */
+               sched_yield();                  /* if this is a portability problem,
+                                                                * remove it */
 
-       fprintf(stderr, "errno is thread-safe\n");
-       
+       fprintf(stderr, "Your errno is thread-safe.\n");
+
+#ifndef HAVE_STRERROR_R
        if (strerror_p1 != strerror_p2)
                strerror_threadsafe = true;
+#endif
 
+#ifndef HAVE_GETPWUID_R
        if (passwd_p1 != passwd_p2)
                getpwuid_threadsafe = true;
+#endif
 
+#if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R)
        if (hostent_p1 != hostent_p2)
                gethostbyname_threadsafe = true;
+#endif
 
        pthread_mutex_unlock(&init_mutex);      /* let children exit  */
-       
+
        pthread_join(thread1, NULL);    /* clean up children */
        pthread_join(thread2, NULL);
 
-       printf("\n");
-
 #ifdef HAVE_STRERROR_R
-       printf("Your system has sterror_r(), so it doesn't use strerror().\n");
+       printf("Your system has sterror_r();  it does not need strerror().\n");
 #else
        printf("Your system uses strerror() which is ");
        if (strerror_threadsafe)
                printf("thread-safe.\n");
        else
        {
-               platform_is_threadsafe = false;
                printf("not thread-safe.\n");
+               platform_is_threadsafe = false;
        }
 #endif
 
 #ifdef HAVE_GETPWUID_R
-       printf("Your system has getpwuid_r(), so it doesn't use getpwuid().\n");
+       printf("Your system has getpwuid_r();  it does not need getpwuid().\n");
 #else
        printf("Your system uses getpwuid() which is ");
        if (getpwuid_threadsafe)
                printf("thread-safe.\n");
        else
        {
-               platform_is_threadsafe = false;
                printf("not thread-safe.\n");
+               platform_is_threadsafe = false;
        }
 #endif
 
 #ifdef HAVE_GETADDRINFO
-       printf("Your system has getaddrinfo(), so it doesn't use gethostbyname()\n"
-                       "  or gethostbyname_r().\n");
+       printf("Your system has getaddrinfo();  it does not need gethostbyname()\n"
+                  "  or gethostbyname_r().\n");
 #else
 #ifdef HAVE_GETHOSTBYNAME_R
-       printf("Your system has gethostbyname_r(), so it doesn't use gethostbyname().\n");
+       printf("Your system has gethostbyname_r();  it does not need gethostbyname().\n");
 #else
        printf("Your system uses gethostbyname which is ");
        if (gethostbyname_threadsafe)
                printf("thread-safe.\n");
        else
        {
-               platform_is_threadsafe = false;
                printf("not thread-safe.\n");
+               platform_is_threadsafe = false;
        }
 #endif
 #endif
 
-       if (!platform_is_threadsafe)
+       if (platform_is_threadsafe)
        {
-               printf("\n** YOUR PLATFORM IS NOT THREADSAFE **\n");
-               return 1;
+               printf("\nYour platform is thread-safe.\n");
+               return 0;
        }
        else
        {
-               printf("\nYOUR PLATFORM IS THREADSAFE\n");
-               return 0;
+               printf("\n** YOUR PLATFORM IS NOT THREAD-SAFE. **\n");
+               return 1;
        }
 }
 
-void func_call_1(void) {
-       void *p;
-       
+void
+func_call_1(void)
+{
+#if !defined(HAVE_GETPWUID_R) || \
+       (!defined(HAVE_GETADDRINFO) && \
+        !defined(HAVE_GETHOSTBYNAME_R))
+       void       *p;
+#endif
+
        unlink("/tmp/thread_test.1");
        /* create, then try to fail on exclusive create open */
        if (open("/tmp/thread_test.1", O_RDWR | O_CREAT, 0600) < 0 ||
                open("/tmp/thread_test.1", O_RDWR | O_CREAT | O_EXCL, 0600) >= 0)
        {
-                       fprintf(stderr, "Could not create file in /tmp or\n");
-                       fprintf(stderr, "could not generate failure for create file in /tmp, exiting\n");
-                       exit(1);
+               fprintf(stderr, "Could not create file in /tmp or\n");
+               fprintf(stderr, "could not generate failure for create file in /tmp, exiting\n");
+               exit(1);
        }
+
        /*
-        *      Wait for other thread to set errno.
-        *      We can't use thread-specific locking here because it might
-        *      affect errno.
+        * Wait for other thread to set errno. We can't use thread-specific
+        * locking here because it might affect errno.
         */
        errno1_set = 1;
        while (errno2_set == 0)
                sched_yield();
        if (errno != EEXIST)
        {
-                       fprintf(stderr, "errno not thread-safe; exiting\n");
-                       unlink("/tmp/thread_test.1");
-                       exit(1);
+               fprintf(stderr, "errno not thread-safe; exiting\n");
+               unlink("/tmp/thread_test.1");
+               exit(1);
        }
        unlink("/tmp/thread_test.1");
-       
+
+#ifndef HAVE_STRERROR_R
        strerror_p1 = strerror(EACCES);
+
        /*
-        *      If strerror() uses sys_errlist, the pointer might change for different
-        *      errno values, so we don't check to see if it varies within the thread.
+        * If strerror() uses sys_errlist, the pointer might change for
+        * different errno values, so we don't check to see if it varies
+        * within the thread.
         */
+#endif
 
+#ifndef HAVE_GETPWUID_R
        passwd_p1 = getpwuid(0);
        p = getpwuid(1);
        if (passwd_p1 != p)
        {
                printf("Your getpwuid() changes the static memory area between calls\n");
-               passwd_p1 = NULL;       /* force thread-safe failure report */
+               passwd_p1 = NULL;               /* force thread-safe failure report */
        }
+#endif
 
+#if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R)
        /* threads do this in opposite order */
        hostent_p1 = gethostbyname(myhostname);
        p = gethostbyname("localhost");
        if (hostent_p1 != p)
        {
                printf("Your gethostbyname() changes the static memory area between calls\n");
-               hostent_p1 = NULL;      /* force thread-safe failure report */
+               hostent_p1 = NULL;              /* force thread-safe failure report */
        }
+#endif
 
        thread1_done = 1;
        pthread_mutex_lock(&init_mutex);        /* wait for parent to test */
@@ -222,54 +244,68 @@ void func_call_1(void) {
 }
 
 
-void func_call_2(void) {
-       void *p;
+void
+func_call_2(void)
+{
+#if !defined(HAVE_GETPWUID_R) || \
+       (!defined(HAVE_GETADDRINFO) && \
+        !defined(HAVE_GETHOSTBYNAME_R))
+       void       *p;
+#endif
 
        unlink("/tmp/thread_test.2");
        /* open non-existant file */
        if (open("/tmp/thread_test.2", O_RDONLY, 0600) >= 0)
        {
-                       fprintf(stderr, "Read-only open succeeded without create, exiting\n");
-                       exit(1);
+               fprintf(stderr, "Read-only open succeeded without create, exiting\n");
+               exit(1);
        }
+
        /*
-        *      Wait for other thread to set errno.
-        *      We can't use thread-specific locking here because it might
-        *      affect errno.
+        * Wait for other thread to set errno. We can't use thread-specific
+        * locking here because it might affect errno.
         */
        errno2_set = 1;
        while (errno1_set == 0)
                sched_yield();
        if (errno != ENOENT)
        {
-                       fprintf(stderr, "errno not thread-safe; exiting\n");
-                       unlink("/tmp/thread_test.A");
-                       exit(1);
+               fprintf(stderr, "errno not thread-safe; exiting\n");
+               unlink("/tmp/thread_test.A");
+               exit(1);
        }
        unlink("/tmp/thread_test.2");
-       
+
+#ifndef HAVE_STRERROR_R
        strerror_p2 = strerror(EINVAL);
+
        /*
-        *      If strerror() uses sys_errlist, the pointer might change for different
-        *      errno values, so we don't check to see if it varies within the thread.
+        * If strerror() uses sys_errlist, the pointer might change for
+        * different errno values, so we don't check to see if it varies
+        * within the thread.
         */
+#endif
 
+#ifndef HAVE_GETPWUID_R
        passwd_p2 = getpwuid(2);
        p = getpwuid(3);
        if (passwd_p2 != p)
        {
                printf("Your getpwuid() changes the static memory area between calls\n");
-               passwd_p2 = NULL;       /* force thread-safe failure report */
+               passwd_p2 = NULL;               /* force thread-safe failure report */
        }
+#endif
 
+#if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R)
        /* threads do this in opposite order */
        hostent_p2 = gethostbyname("localhost");
        p = gethostbyname(myhostname);
        if (hostent_p2 != p)
        {
                printf("Your gethostbyname() changes the static memory area between calls\n");
-               hostent_p2 = NULL;      /* force thread-safe failure report */
+               hostent_p2 = NULL;              /* force thread-safe failure report */
        }
+#endif
 
        thread2_done = 1;
        pthread_mutex_lock(&init_mutex);        /* wait for parent to test */