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