(root)/
gcc-13.2.0/
libgomp/
config/
posix/
lock.c
       1  /* Copyright (C) 2005-2023 Free Software Foundation, Inc.
       2     Contributed by Richard Henderson <rth@redhat.com>.
       3  
       4     This file is part of the GNU Offloading and Multi Processing Library
       5     (libgomp).
       6  
       7     Libgomp is free software; you can redistribute it and/or modify it
       8     under the terms of the GNU General Public License as published by
       9     the Free Software Foundation; either version 3, or (at your option)
      10     any later version.
      11  
      12     Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
      13     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      14     FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
      15     more details.
      16  
      17     Under Section 7 of GPL version 3, you are granted additional
      18     permissions described in the GCC Runtime Library Exception, version
      19     3.1, as published by the Free Software Foundation.
      20  
      21     You should have received a copy of the GNU General Public License and
      22     a copy of the GCC Runtime Library Exception along with this program;
      23     see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      24     <http://www.gnu.org/licenses/>.  */
      25  
      26  /* This is the default PTHREADS implementation of the public OpenMP
      27     locking primitives.
      28  
      29     Because OpenMP uses different entry points for normal and recursive
      30     locks, and pthreads uses only one entry point, a system may be able
      31     to do better and streamline the locking as well as reduce the size
      32     of the types exported.  */
      33  
      34  /* We need UNIX98/XPG5 extensions to get recursive locks.  Request XPG6 since
      35     Solaris requires this for C99 and later.  */
      36  #define _XOPEN_SOURCE 600
      37  
      38  #include "libgomp.h"
      39  
      40  #ifdef HAVE_BROKEN_POSIX_SEMAPHORES
      41  void
      42  gomp_init_lock_30 (omp_lock_t *lock)
      43  {
      44    pthread_mutex_init (lock, NULL);
      45  }
      46  
      47  void
      48  gomp_destroy_lock_30 (omp_lock_t *lock)
      49  {
      50    pthread_mutex_destroy (lock);
      51  }
      52  
      53  void
      54  gomp_set_lock_30 (omp_lock_t *lock)
      55  {
      56    pthread_mutex_lock (lock);
      57  }
      58  
      59  void
      60  gomp_unset_lock_30 (omp_lock_t *lock)
      61  {
      62    pthread_mutex_unlock (lock);
      63  }
      64  
      65  int
      66  gomp_test_lock_30 (omp_lock_t *lock)
      67  {
      68    return pthread_mutex_trylock (lock) == 0;
      69  }
      70  
      71  void
      72  gomp_init_nest_lock_30 (omp_nest_lock_t *lock)
      73  {
      74    pthread_mutex_init (&lock->lock, NULL);
      75    lock->count = 0;
      76    lock->owner = NULL;
      77  }
      78  
      79  void
      80  gomp_destroy_nest_lock_30 (omp_nest_lock_t *lock)
      81  {
      82    pthread_mutex_destroy (&lock->lock);
      83  }
      84  
      85  void
      86  gomp_set_nest_lock_30 (omp_nest_lock_t *lock)
      87  {
      88    void *me = gomp_icv (true);
      89  
      90    if (lock->owner != me)
      91      {
      92        pthread_mutex_lock (&lock->lock);
      93        lock->owner = me;
      94      }
      95    lock->count++;
      96  }
      97  
      98  void
      99  gomp_unset_nest_lock_30 (omp_nest_lock_t *lock)
     100  {
     101    if (--lock->count == 0)
     102      {
     103        lock->owner = NULL;
     104        pthread_mutex_unlock (&lock->lock);
     105      }
     106  }
     107  
     108  int
     109  gomp_test_nest_lock_30 (omp_nest_lock_t *lock)
     110  {
     111    void *me = gomp_icv (true);
     112  
     113    if (lock->owner != me)
     114      {
     115        if (pthread_mutex_trylock (&lock->lock) != 0)
     116  	return 0;
     117        lock->owner = me;
     118      }
     119  
     120    return ++lock->count;
     121  }
     122  
     123  #else
     124  
     125  void
     126  gomp_init_lock_30 (omp_lock_t *lock)
     127  {
     128    sem_init (lock, 0, 1);
     129  }
     130  
     131  void
     132  gomp_destroy_lock_30 (omp_lock_t *lock)
     133  {
     134    sem_destroy (lock);
     135  }
     136  
     137  void
     138  gomp_set_lock_30 (omp_lock_t *lock)
     139  {
     140    while (sem_wait (lock) != 0)
     141      ;
     142  }
     143  
     144  void
     145  gomp_unset_lock_30 (omp_lock_t *lock)
     146  {
     147    sem_post (lock);
     148  }
     149  
     150  int
     151  gomp_test_lock_30 (omp_lock_t *lock)
     152  {
     153    return sem_trywait (lock) == 0;
     154  }
     155  
     156  void
     157  gomp_init_nest_lock_30 (omp_nest_lock_t *lock)
     158  {
     159    sem_init (&lock->lock, 0, 1);
     160    lock->count = 0;
     161    lock->owner = NULL;
     162  }
     163  
     164  void
     165  gomp_destroy_nest_lock_30 (omp_nest_lock_t *lock)
     166  {
     167    sem_destroy (&lock->lock);
     168  }
     169  
     170  void
     171  gomp_set_nest_lock_30 (omp_nest_lock_t *lock)
     172  {
     173    void *me = gomp_icv (true);
     174  
     175    if (lock->owner != me)
     176      {
     177        while (sem_wait (&lock->lock) != 0)
     178  	;
     179        lock->owner = me;
     180      }
     181    lock->count++;
     182  }
     183  
     184  void
     185  gomp_unset_nest_lock_30 (omp_nest_lock_t *lock)
     186  {
     187    if (--lock->count == 0)
     188      {
     189        lock->owner = NULL;
     190        sem_post (&lock->lock);
     191      }
     192  }
     193  
     194  int
     195  gomp_test_nest_lock_30 (omp_nest_lock_t *lock)
     196  {
     197    void *me = gomp_icv (true);
     198  
     199    if (lock->owner != me)
     200      {
     201        if (sem_trywait (&lock->lock) != 0)
     202  	return 0;
     203        lock->owner = me;
     204      }
     205  
     206    return ++lock->count;
     207  }
     208  #endif
     209  
     210  #ifdef LIBGOMP_GNU_SYMBOL_VERSIONING
     211  void
     212  gomp_init_lock_25 (omp_lock_25_t *lock)
     213  {
     214    pthread_mutex_init (lock, NULL);
     215  }
     216  
     217  void
     218  gomp_destroy_lock_25 (omp_lock_25_t *lock)
     219  {
     220    pthread_mutex_destroy (lock);
     221  }
     222  
     223  void
     224  gomp_set_lock_25 (omp_lock_25_t *lock)
     225  {
     226    pthread_mutex_lock (lock);
     227  }
     228  
     229  void
     230  gomp_unset_lock_25 (omp_lock_25_t *lock)
     231  {
     232    pthread_mutex_unlock (lock);
     233  }
     234  
     235  int
     236  gomp_test_lock_25 (omp_lock_25_t *lock)
     237  {
     238    return pthread_mutex_trylock (lock) == 0;
     239  }
     240  
     241  void
     242  gomp_init_nest_lock_25 (omp_nest_lock_25_t *lock)
     243  {
     244    pthread_mutexattr_t attr;
     245  
     246    pthread_mutexattr_init (&attr);
     247    pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
     248    pthread_mutex_init (&lock->lock, &attr);
     249    lock->count = 0;
     250    pthread_mutexattr_destroy (&attr);
     251  }
     252  
     253  void
     254  gomp_destroy_nest_lock_25 (omp_nest_lock_25_t *lock)
     255  {
     256    pthread_mutex_destroy (&lock->lock);
     257  }
     258  
     259  void
     260  gomp_set_nest_lock_25 (omp_nest_lock_25_t *lock)
     261  {
     262    pthread_mutex_lock (&lock->lock);
     263    lock->count++;
     264  }
     265  
     266  void
     267  gomp_unset_nest_lock_25 (omp_nest_lock_25_t *lock)
     268  {
     269    lock->count--;
     270    pthread_mutex_unlock (&lock->lock);
     271  }
     272  
     273  int
     274  gomp_test_nest_lock_25 (omp_nest_lock_25_t *lock)
     275  {
     276    if (pthread_mutex_trylock (&lock->lock) == 0)
     277      return ++lock->count;
     278    return 0;
     279  }
     280  
     281  omp_lock_symver (omp_init_lock)
     282  omp_lock_symver (omp_destroy_lock)
     283  omp_lock_symver (omp_set_lock)
     284  omp_lock_symver (omp_unset_lock)
     285  omp_lock_symver (omp_test_lock)
     286  omp_lock_symver (omp_init_nest_lock)
     287  omp_lock_symver (omp_destroy_nest_lock)
     288  omp_lock_symver (omp_set_nest_lock)
     289  omp_lock_symver (omp_unset_nest_lock)
     290  omp_lock_symver (omp_test_nest_lock)
     291  
     292  #else
     293  
     294  ialias (omp_init_lock)
     295  ialias (omp_init_nest_lock)
     296  ialias (omp_destroy_lock)
     297  ialias (omp_destroy_nest_lock)
     298  ialias (omp_set_lock)
     299  ialias (omp_set_nest_lock)
     300  ialias (omp_unset_lock)
     301  ialias (omp_unset_nest_lock)
     302  ialias (omp_test_lock)
     303  ialias (omp_test_nest_lock)
     304  
     305  #endif