sem.c revision 1.1
10Sduke/* Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc. 22362Sohair Contributed by Richard Henderson <rth@redhat.com>. 30Sduke 40Sduke This file is part of the GNU OpenMP Library (libgomp). 50Sduke 60Sduke Libgomp is free software; you can redistribute it and/or modify it 70Sduke under the terms of the GNU General Public License as published by 80Sduke the Free Software Foundation; either version 3, or (at your option) 90Sduke any later version. 100Sduke 110Sduke Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY 120Sduke WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 130Sduke FOR A PARTICULAR PURPOSE. See the GNU General Public License for 140Sduke more details. 150Sduke 160Sduke Under Section 7 of GPL version 3, you are granted additional 170Sduke permissions described in the GCC Runtime Library Exception, version 180Sduke 3.1, as published by the Free Software Foundation. 192362Sohair 202362Sohair You should have received a copy of the GNU General Public License and 212362Sohair a copy of the GCC Runtime Library Exception along with this program; 220Sduke see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 230Sduke <http://www.gnu.org/licenses/>. */ 240Sduke 250Sduke/* This is a Linux specific implementation of a semaphore synchronization 260Sduke mechanism for libgomp. This type is private to the library. This 270Sduke implementation uses atomic instructions and the futex syscall. */ 280Sduke 290Sduke#include "wait.h" 300Sduke 310Sduke 320Sdukevoid 330Sdukegomp_sem_wait_slow (gomp_sem_t *sem) 340Sduke{ 350Sduke while (1) 360Sduke { 370Sduke int val = __sync_val_compare_and_swap (sem, 0, -1); 380Sduke if (val > 0) 390Sduke { 400Sduke if (__sync_bool_compare_and_swap (sem, val, val - 1)) 410Sduke return; 420Sduke } 430Sduke do_wait (sem, -1); 440Sduke } 450Sduke} 460Sduke 470Sdukevoid 480Sdukegomp_sem_post_slow (gomp_sem_t *sem) 490Sduke{ 500Sduke int old, tmp = *sem, wake; 510Sduke 520Sduke do 530Sduke { 54 old = tmp; 55 wake = old > 0 ? old + 1 : 1; 56 tmp = __sync_val_compare_and_swap (sem, old, wake); 57 } 58 while (old != tmp); 59 60 futex_wake (sem, wake); 61} 62