(root)/
glibc-2.38/
htl/
tests/
test-11.c
       1  /* Test rwlocks.
       2     Copyright (C) 2000-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library;  if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #define _GNU_SOURCE
      20  
      21  #include <pthread.h>
      22  #include <assert.h>
      23  #include <error.h>
      24  #include <errno.h>
      25  
      26  #define THREADS 1
      27  
      28  int a;
      29  int b;
      30  
      31  /* Get a read lock and assert that a == b.  */
      32  void *
      33  test1 (void *arg)
      34  {
      35    error_t err;
      36    pthread_rwlock_t *lock = arg;
      37    int i;
      38  
      39    for (i = 0; i < 200; i++)
      40      {
      41        err = pthread_rwlock_rdlock (lock);
      42        assert (err == 0);
      43  
      44        assert (a == b);
      45  
      46        sched_yield ();
      47  
      48        assert (a == b);
      49  
      50        err = pthread_rwlock_unlock (lock);
      51        assert (err == 0);
      52      }
      53  
      54    return 0;
      55  }
      56  
      57  int
      58  main (int argc, char **argv)
      59  {
      60    error_t err;
      61    pthread_rwlockattr_t attr;
      62    pthread_rwlock_t lock;
      63    int pshared;
      64  
      65    int i;
      66    pthread_t tid[THREADS];
      67    void *ret;
      68  
      69    err = pthread_rwlockattr_init (&attr);
      70    if (err)
      71      error (1, err, "pthread_rwlockattr_init");
      72  
      73    err = pthread_rwlockattr_getpshared (&attr, &pshared);
      74    if (err)
      75      error (1, err, "pthread_rwlockattr_getpshared");
      76  
      77    /* Assert the default state as mandated by POSIX.  */
      78    assert (pshared == PTHREAD_PROCESS_PRIVATE);
      79  
      80    err = pthread_rwlockattr_setpshared (&attr, pshared);
      81    if (err)
      82      error (1, err, "pthread_rwlockattr_setpshared");
      83  
      84    err = pthread_rwlock_init (&lock, &attr);
      85    if (err)
      86      error (1, err, "pthread_rwlock_init");
      87  
      88    err = pthread_rwlockattr_destroy (&attr);
      89    if (err)
      90      error (1, err, "pthread_rwlockattr_destroy");
      91  
      92    /* Now test the lock.  */
      93  
      94    for (i = 0; i < THREADS; i++)
      95      {
      96        err = pthread_create (&tid[i], 0, test1, &lock);
      97        if (err)
      98  	error (1, err, "pthread_create");
      99      }
     100  
     101    for (i = 0; i < 10; i++)
     102      {
     103        sched_yield ();
     104  
     105        /* Get a write lock.  */
     106        pthread_rwlock_wrlock (&lock);
     107        /* Increment a and b giving other threads a chance to run in
     108           between.  */
     109        sched_yield ();
     110        a++;
     111        sched_yield ();
     112        b++;
     113        sched_yield ();
     114        /* Unlock.  */
     115        pthread_rwlock_unlock (&lock);
     116      }
     117  
     118    for (i = 0; i < THREADS; i++)
     119      {
     120        err = pthread_join (tid[i], &ret);
     121        if (err)
     122  	error (1, err, "pthread_join");
     123      }
     124  
     125    /* Read lock it.  */
     126    err = pthread_rwlock_tryrdlock (&lock);
     127    assert (err == 0);
     128  
     129    /* Try to write lock it.  It should fail with EBUSY.  */
     130    err = pthread_rwlock_trywrlock (&lock);
     131    assert (err == EBUSY);
     132  
     133    /* Drop the read lock.  */
     134    err = pthread_rwlock_unlock (&lock);
     135    assert (err == 0);
     136  
     137    /* Get a write lock.  */
     138    err = pthread_rwlock_trywrlock (&lock);
     139    assert (err == 0);
     140  
     141    /* Fail trying to acquire another write lock.  */
     142    err = pthread_rwlock_trywrlock (&lock);
     143    assert (err == EBUSY);
     144  
     145    /* Try to get a read lock which should also fail.  */
     146    err = pthread_rwlock_tryrdlock (&lock);
     147    assert (err == EBUSY);
     148  
     149    /* Unlock it.  */
     150    err = pthread_rwlock_unlock (&lock);
     151    assert (err == 0);
     152  
     153  
     154    err = pthread_rwlock_destroy (&lock);
     155    if (err)
     156      error (1, err, "pthread_rwlock_destroy");
     157  
     158    return 0;
     159  }