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