sem.c revision 169695
1139825Simp/* Copyright (C) 2005 Free Software Foundation, Inc. 21549Srgrimes Contributed by Richard Henderson <rth@redhat.com>. 31549Srgrimes 44Srgrimes This file is part of the GNU OpenMP Library (libgomp). 54Srgrimes 64Srgrimes Libgomp is free software; you can redistribute it and/or modify it 74Srgrimes under the terms of the GNU Lesser General Public License as published by 84Srgrimes the Free Software Foundation; either version 2.1 of the License, or 94Srgrimes (at your option) any later version. 104Srgrimes 114Srgrimes Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY 124Srgrimes WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 134Srgrimes FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 144Srgrimes more details. 154Srgrimes 164Srgrimes You should have received a copy of the GNU Lesser General Public License 174Srgrimes along with libgomp; see the file COPYING.LIB. If not, write to the 184Srgrimes Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 194Srgrimes MA 02110-1301, USA. */ 204Srgrimes 214Srgrimes/* As a special exception, if you link this library with other files, some 224Srgrimes of which are compiled with GCC, to produce an executable, this library 234Srgrimes does not by itself cause the resulting executable to be covered by the 244Srgrimes GNU General Public License. This exception does not however invalidate 254Srgrimes any other reasons why the executable file might be covered by the GNU 264Srgrimes General Public License. */ 274Srgrimes 284Srgrimes/* This is a Linux specific implementation of a semaphore synchronization 291549Srgrimes mechanism for libgomp. This type is private to the library. This 3050477Speter implementation uses atomic instructions and the futex syscall. */ 314Srgrimes 324Srgrimes#include "libgomp.h" 33115164Skan#include "futex.h" 346165Sbde 35719Swollman 36143063Sjoergvoid 37143063Sjoerggomp_sem_wait_slow (gomp_sem_t *sem) 38143063Sjoerg{ 39114216Skan while (1) 4047347Sache { 4147347Sache int val = __sync_val_compare_and_swap (sem, 0, -1); 42114216Skan if (val > 0) 431549Srgrimes { 446165Sbde if (__sync_bool_compare_and_swap (sem, val, val - 1)) 45 return; 46 } 47 futex_wait (sem, -1); 48 } 49} 50 51void 52gomp_sem_post_slow (gomp_sem_t *sem) 53{ 54 int old, tmp = *sem, wake; 55 56 do 57 { 58 old = tmp; 59 wake = old > 0 ? old + 1 : 1; 60 tmp = __sync_val_compare_and_swap (sem, old, wake); 61 } 62 while (old != tmp); 63 64 futex_wake (sem, wake); 65} 66