(root)/
glibc-2.38/
nptl/
tst-rwlock8.c
       1  /* Test program for timedout read/write lock functions.
       2     Copyright (C) 2000-2023 Free Software Foundation, Inc.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public License as
       6     published by the Free Software Foundation; either version 2.1 of the
       7     License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; see the file COPYING.LIB.  If
      16     not, see <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <errno.h>
      19  #include <error.h>
      20  #include <pthread.h>
      21  #include <stdio.h>
      22  #include <stdlib.h>
      23  #include <time.h>
      24  #include <unistd.h>
      25  
      26  
      27  #define NWRITERS 15
      28  #define WRITETRIES 10
      29  #define NREADERS 15
      30  #define READTRIES 15
      31  
      32  #define DELAY   1000000
      33  
      34  #ifndef KIND
      35  # define KIND PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
      36  #endif
      37  
      38  static pthread_rwlock_t lock;
      39  
      40  
      41  static void *
      42  writer_thread (void *nr)
      43  {
      44    struct timespec delay;
      45    int n;
      46  
      47    delay.tv_sec = 0;
      48    delay.tv_nsec = DELAY;
      49  
      50    for (n = 0; n < WRITETRIES; ++n)
      51      {
      52        printf ("writer thread %ld tries again\n", (long int) nr);
      53  
      54        if (pthread_rwlock_wrlock (&lock) != 0)
      55  	{
      56  	  puts ("wrlock failed");
      57  	  exit (1);
      58  	}
      59  
      60        printf ("writer thread %ld succeeded\n", (long int) nr);
      61  
      62        nanosleep (&delay, NULL);
      63  
      64        if (pthread_rwlock_unlock (&lock) != 0)
      65  	{
      66  	  puts ("unlock for writer failed");
      67  	  exit (1);
      68  	}
      69  
      70        printf ("writer thread %ld released\n", (long int) nr);
      71      }
      72  
      73    return NULL;
      74  }
      75  
      76  
      77  static void *
      78  reader_thread (void *nr)
      79  {
      80    struct timespec delay;
      81    int n;
      82  
      83    delay.tv_sec = 0;
      84    delay.tv_nsec = DELAY;
      85  
      86    for (n = 0; n < READTRIES; ++n)
      87      {
      88        printf ("reader thread %ld tries again\n", (long int) nr);
      89  
      90        if (pthread_rwlock_rdlock (&lock) != 0)
      91  	{
      92  	  puts ("rdlock failed");
      93  	  exit (1);
      94  	}
      95  
      96        printf ("reader thread %ld succeeded\n", (long int) nr);
      97  
      98        nanosleep (&delay, NULL);
      99  
     100        if (pthread_rwlock_unlock (&lock) != 0)
     101  	{
     102  	  puts ("unlock for reader failed");
     103  	  exit (1);
     104  	}
     105  
     106        printf ("reader thread %ld released\n", (long int) nr);
     107      }
     108  
     109    return NULL;
     110  }
     111  
     112  
     113  static int
     114  do_test (void)
     115  {
     116    pthread_t thwr[NWRITERS];
     117    pthread_t thrd[NREADERS];
     118    int n;
     119    void *res;
     120    pthread_rwlockattr_t a;
     121  
     122    if (pthread_rwlockattr_init (&a) != 0)
     123      {
     124        puts ("rwlockattr_t failed");
     125        exit (1);
     126      }
     127  
     128    if (pthread_rwlockattr_setkind_np (&a, KIND) != 0)
     129      {
     130        puts ("rwlockattr_setkind failed");
     131        exit (1);
     132      }
     133  
     134    if (pthread_rwlock_init (&lock, &a) != 0)
     135      {
     136        puts ("rwlock_init failed");
     137        exit (1);
     138      }
     139  
     140    /* Make standard error the same as standard output.  */
     141    dup2 (1, 2);
     142  
     143    /* Make sure we see all message, even those on stdout.  */
     144    setvbuf (stdout, NULL, _IONBF, 0);
     145  
     146    for (n = 0; n < NWRITERS; ++n)
     147      if (pthread_create (&thwr[n], NULL, writer_thread,
     148  			(void *) (long int) n) != 0)
     149        {
     150  	puts ("writer create failed");
     151  	exit (1);
     152        }
     153  
     154    for (n = 0; n < NREADERS; ++n)
     155      if (pthread_create (&thrd[n], NULL, reader_thread,
     156  			(void *) (long int) n) != 0)
     157        {
     158  	puts ("reader create failed");
     159  	exit (1);
     160        }
     161  
     162    /* Wait for all the threads.  */
     163    for (n = 0; n < NWRITERS; ++n)
     164      if (pthread_join (thwr[n], &res) != 0)
     165        {
     166  	puts ("writer join failed");
     167  	exit (1);
     168        }
     169    for (n = 0; n < NREADERS; ++n)
     170      if (pthread_join (thrd[n], &res) != 0)
     171        {
     172  	puts ("reader join failed");
     173  	exit (1);
     174        }
     175  
     176    return 0;
     177  }
     178  
     179  #define TIMEOUT 30
     180  #define TEST_FUNCTION do_test ()
     181  #include "../test-skeleton.c"