(root)/
glibc-2.38/
sysdeps/
pthread/
tst-cond16.c
       1  /* Copyright (C) 2004-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       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
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the 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; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <errno.h>
      19  #include <limits.h>
      20  #include <pthread.h>
      21  #include <stdbool.h>
      22  #include <stdio.h>
      23  #include <stdlib.h>
      24  #include <unistd.h>
      25  
      26  pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
      27  pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
      28  bool n, exiting;
      29  FILE *f;
      30  enum { count = 8 };		/* Number of worker threads.  */
      31  
      32  void *
      33  tf (void *dummy)
      34  {
      35    bool loop = true;
      36  
      37    while (loop)
      38      {
      39        pthread_mutex_lock (&lock);
      40        while (n && !exiting)
      41  	pthread_cond_wait (&cv, &lock);
      42        n = true;
      43        pthread_mutex_unlock (&lock);
      44  
      45        fputs (".", f);
      46  
      47        pthread_mutex_lock (&lock);
      48        n = false;
      49        if (exiting)
      50  	loop = false;
      51  #ifdef UNLOCK_AFTER_BROADCAST
      52        pthread_cond_broadcast (&cv);
      53        pthread_mutex_unlock (&lock);
      54  #else
      55        pthread_mutex_unlock (&lock);
      56        pthread_cond_broadcast (&cv);
      57  #endif
      58      }
      59  
      60    return NULL;
      61  }
      62  
      63  int
      64  do_test (void)
      65  {
      66    f = fopen ("/dev/null", "w");
      67    if (f == NULL)
      68      {
      69        printf ("couldn't open /dev/null, %m\n");
      70        return 1;
      71      }
      72  
      73    pthread_t th[count];
      74    pthread_attr_t attr;
      75    int i, ret, sz;
      76    pthread_attr_init (&attr);
      77    sz = sysconf (_SC_PAGESIZE);
      78  #ifdef PTHREAD_STACK_MIN
      79    if (sz < PTHREAD_STACK_MIN)
      80  	  sz = PTHREAD_STACK_MIN;
      81  #endif
      82    pthread_attr_setstacksize (&attr, sz);
      83    for (i = 0; i < count; ++i)
      84      if ((ret = pthread_create (&th[i], &attr, tf, NULL)) != 0)
      85        {
      86  	errno = ret;
      87  	printf ("pthread_create %d failed: %m\n", i);
      88  	return 1;
      89        }
      90  
      91    struct timespec ts = { .tv_sec = 20, .tv_nsec = 0 };
      92    while (nanosleep (&ts, &ts) != 0);
      93  
      94    pthread_mutex_lock (&lock);
      95    exiting = true;
      96    pthread_mutex_unlock (&lock);
      97  
      98    for (i = 0; i < count; ++i)
      99      pthread_join (th[i], NULL);
     100  
     101    fclose (f);
     102    return 0;
     103  }
     104  
     105  #define TEST_FUNCTION do_test ()
     106  #define TIMEOUT 40
     107  #include "../test-skeleton.c"