sema.c revision 4cfea4f9480393ed6799db463b2e0fb8865a1a2f
143b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn 243b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn/*--------------------------------------------------------------------*/ 3278b3d6ff7b7a311ab49dff993b4aaf42b09ef13njn/*--- Semaphore stuff. sema.c ---*/ 443b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn/*--------------------------------------------------------------------*/ 543b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn 643b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn/* 743b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn This file is part of Valgrind, a dynamic binary instrumentation 843b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn framework. 943b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn 10e4b0bf07b0ee0a18eacc5aba91686ab5fc1d327bsewardj Copyright (C) 2000-2006 Julian Seward 1143b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn jseward@acm.org 1243b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn 1343b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn This program is free software; you can redistribute it and/or 1443b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn modify it under the terms of the GNU General Public License as 1543b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn published by the Free Software Foundation; either version 2 of the 1643b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn License, or (at your option) any later version. 1743b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn 1843b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn This program is distributed in the hope that it will be useful, but 1943b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn WITHOUT ANY WARRANTY; without even the implied warranty of 2043b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 2143b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn General Public License for more details. 2243b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn 2343b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn You should have received a copy of the GNU General Public License 2443b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn along with this program; if not, write to the Free Software 2543b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 2643b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn 02111-1307, USA. 2743b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn 2843b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn The GNU General Public License is contained in the file COPYING. 2943b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn*/ 3043b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn 31c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_core_basics.h" 324cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj#include "pub_core_vki.h" 33132bfccd21960e462352175f8553a5bdce8a210cnjn#include "pub_core_libcassert.h" 34eb8896b58301a0a7a34281384d705072994369f0njn#include "pub_core_libcfile.h" 35f4c50164b9a89e3421cd6650f7187bd46b936cbdnjn#include "pub_core_libcproc.h" // For VG_(gettid)() 36278b3d6ff7b7a311ab49dff993b4aaf42b09ef13njn#include "priv_sema.h" 37cbdddcfb32883a37e873907602d34bac523e3eadsewardj 38cbdddcfb32883a37e873907602d34bac523e3eadsewardj/* 39beb7ffa741dca68fd9e94622309d1f4cb232e8aanjn Slower (than the removed futex-based sema scheme) but more portable 40beb7ffa741dca68fd9e94622309d1f4cb232e8aanjn pipe-based token passing scheme. 41cbdddcfb32883a37e873907602d34bac523e3eadsewardj */ 42cbdddcfb32883a37e873907602d34bac523e3eadsewardj 437eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjvoid ML_(sema_init)(vg_sema_t *sema) 44cbdddcfb32883a37e873907602d34bac523e3eadsewardj{ 4583008d6f1610fdf29639ae31381b26c876b57e9fsewardj Int res; 46cbdddcfb32883a37e873907602d34bac523e3eadsewardj VG_(pipe)(sema->pipe); 47cbdddcfb32883a37e873907602d34bac523e3eadsewardj sema->pipe[0] = VG_(safe_fd)(sema->pipe[0]); 48cbdddcfb32883a37e873907602d34bac523e3eadsewardj sema->pipe[1] = VG_(safe_fd)(sema->pipe[1]); 49cbdddcfb32883a37e873907602d34bac523e3eadsewardj 50cbdddcfb32883a37e873907602d34bac523e3eadsewardj sema->owner_thread = -1; 51cbdddcfb32883a37e873907602d34bac523e3eadsewardj 52cbdddcfb32883a37e873907602d34bac523e3eadsewardj /* create initial token */ 5383008d6f1610fdf29639ae31381b26c876b57e9fsewardj res = VG_(write)(sema->pipe[1], "T", 1); 5483008d6f1610fdf29639ae31381b26c876b57e9fsewardj vg_assert(res == 1); 55cbdddcfb32883a37e873907602d34bac523e3eadsewardj} 56cbdddcfb32883a37e873907602d34bac523e3eadsewardj 577eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjvoid ML_(sema_deinit)(vg_sema_t *sema) 58cbdddcfb32883a37e873907602d34bac523e3eadsewardj{ 59cbdddcfb32883a37e873907602d34bac523e3eadsewardj VG_(close)(sema->pipe[0]); 60cbdddcfb32883a37e873907602d34bac523e3eadsewardj VG_(close)(sema->pipe[1]); 61cbdddcfb32883a37e873907602d34bac523e3eadsewardj sema->pipe[0] = sema->pipe[1] = -1; 62cbdddcfb32883a37e873907602d34bac523e3eadsewardj} 63cbdddcfb32883a37e873907602d34bac523e3eadsewardj 64cbdddcfb32883a37e873907602d34bac523e3eadsewardj/* get a token */ 657eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjvoid ML_(sema_down)(vg_sema_t *sema) 66cbdddcfb32883a37e873907602d34bac523e3eadsewardj{ 67cbdddcfb32883a37e873907602d34bac523e3eadsewardj Char buf[2] = { 'x' }; 68cbdddcfb32883a37e873907602d34bac523e3eadsewardj Int ret; 69cbdddcfb32883a37e873907602d34bac523e3eadsewardj Int lwpid = VG_(gettid)(); 70cbdddcfb32883a37e873907602d34bac523e3eadsewardj 71cbdddcfb32883a37e873907602d34bac523e3eadsewardj vg_assert(sema->owner_thread != lwpid); /* can't have it already */ 72cbdddcfb32883a37e873907602d34bac523e3eadsewardj 73cbdddcfb32883a37e873907602d34bac523e3eadsewardj again: 74cbdddcfb32883a37e873907602d34bac523e3eadsewardj ret = VG_(read)(sema->pipe[0], buf, 2); 75cbdddcfb32883a37e873907602d34bac523e3eadsewardj 76cbdddcfb32883a37e873907602d34bac523e3eadsewardj if (ret == -VKI_EINTR) 77cbdddcfb32883a37e873907602d34bac523e3eadsewardj goto again; 78cbdddcfb32883a37e873907602d34bac523e3eadsewardj 79cbdddcfb32883a37e873907602d34bac523e3eadsewardj vg_assert(ret == 1); /* should get exactly 1 token */ 80cbdddcfb32883a37e873907602d34bac523e3eadsewardj vg_assert(buf[0] == 'T'); 81cbdddcfb32883a37e873907602d34bac523e3eadsewardj 82cbdddcfb32883a37e873907602d34bac523e3eadsewardj sema->owner_thread = lwpid; 83cbdddcfb32883a37e873907602d34bac523e3eadsewardj} 84cbdddcfb32883a37e873907602d34bac523e3eadsewardj 85cbdddcfb32883a37e873907602d34bac523e3eadsewardj/* put token back */ 867eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjvoid ML_(sema_up)(vg_sema_t *sema) 87cbdddcfb32883a37e873907602d34bac523e3eadsewardj{ 88cbdddcfb32883a37e873907602d34bac523e3eadsewardj Int ret; 89cbdddcfb32883a37e873907602d34bac523e3eadsewardj 90cbdddcfb32883a37e873907602d34bac523e3eadsewardj vg_assert(sema->owner_thread == VG_(gettid)()); /* must have it */ 91cbdddcfb32883a37e873907602d34bac523e3eadsewardj 92cbdddcfb32883a37e873907602d34bac523e3eadsewardj sema->owner_thread = 0; 93cbdddcfb32883a37e873907602d34bac523e3eadsewardj 94cbdddcfb32883a37e873907602d34bac523e3eadsewardj ret = VG_(write)(sema->pipe[1], "T", 1); 95cbdddcfb32883a37e873907602d34bac523e3eadsewardj vg_assert(ret == 1); 96cbdddcfb32883a37e873907602d34bac523e3eadsewardj} 97cbdddcfb32883a37e873907602d34bac523e3eadsewardj 9843b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn/*--------------------------------------------------------------------*/ 9943b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn/*--- end ---*/ 10043b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn/*--------------------------------------------------------------------*/ 10143b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn 10243b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn 103