138032Speter/* Copyright (C) 2005 Free Software Foundation, Inc. 238032Speter Contributed by Richard Henderson <rth@redhat.com>. 338032Speter 438032Speter This file is part of the GNU OpenMP Library (libgomp). 538032Speter 638032Speter Libgomp is free software; you can redistribute it and/or modify it 738032Speter under the terms of the GNU Lesser General Public License as published by 8285303Sgshapiro the Free Software Foundation; either version 2.1 of the License, or 9285303Sgshapiro (at your option) any later version. 10285303Sgshapiro 11285303Sgshapiro Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY 12285303Sgshapiro WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13285303Sgshapiro FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 14285303Sgshapiro more details. 15285303Sgshapiro 16285303Sgshapiro You should have received a copy of the GNU Lesser General Public License 17285303Sgshapiro along with libgomp; see the file COPYING.LIB. If not, write to the 18285303Sgshapiro Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 19285303Sgshapiro MA 02110-1301, USA. */ 20285303Sgshapiro 21285303Sgshapiro/* As a special exception, if you link this library with other files, some 22285303Sgshapiro of which are compiled with GCC, to produce an executable, this library 23285303Sgshapiro does not by itself cause the resulting executable to be covered by the 24285303Sgshapiro GNU General Public License. This exception does not however invalidate 25285303Sgshapiro any other reasons why the executable file might be covered by the GNU 26285303Sgshapiro General Public License. */ 27285303Sgshapiro 28285303Sgshapiro/* This is a Linux specific implementation of a semaphore synchronization 29285303Sgshapiro mechanism for libgomp. This type is private to the library. This 30285303Sgshapiro implementation uses atomic instructions and the futex syscall. */ 31285303Sgshapiro 32285303Sgshapiro#include "libgomp.h" 33285303Sgshapiro#include "futex.h" 34285303Sgshapiro 35285303Sgshapiro 36285303Sgshapirovoid 37285303Sgshapirogomp_sem_wait_slow (gomp_sem_t *sem) 38285303Sgshapiro{ 39285303Sgshapiro while (1) 40285303Sgshapiro { 41285303Sgshapiro int val = __sync_val_compare_and_swap (sem, 0, -1); 42285303Sgshapiro if (val > 0) 43285303Sgshapiro { 44285303Sgshapiro if (__sync_bool_compare_and_swap (sem, val, val - 1)) 45285303Sgshapiro return; 46285303Sgshapiro } 47285303Sgshapiro futex_wait (sem, -1); 48285303Sgshapiro } 49285303Sgshapiro} 50285303Sgshapiro 51285303Sgshapirovoid 52285303Sgshapirogomp_sem_post_slow (gomp_sem_t *sem) 53285303Sgshapiro{ 54285303Sgshapiro int old, tmp = *sem, wake; 55285303Sgshapiro 56285303Sgshapiro do 57285303Sgshapiro { 58285303Sgshapiro old = tmp; 59285303Sgshapiro wake = old > 0 ? old + 1 : 1; 60285303Sgshapiro tmp = __sync_val_compare_and_swap (sem, old, wake); 61285303Sgshapiro } 62285303Sgshapiro while (old != tmp); 63285303Sgshapiro 64285303Sgshapiro futex_wake (sem, wake); 65285303Sgshapiro} 66285303Sgshapiro