drd_pthread_intercepts.c revision 4f66a77e12665587f10b550fe438c3bd2f257b32
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* -*- mode: C; c-basic-offset: 3; -*- */ 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*--------------------------------------------------------------------*/ 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*--- Client-space code for DRD. drd_pthread_intercepts.c ---*/ 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*--------------------------------------------------------------------*/ 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project This file is part of DRD, a thread error detector. 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Copyright (C) 2006-2009 Bart Van Assche <bart.vanassche@gmail.com>. 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project This program is free software; you can redistribute it and/or 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modify it under the terms of the GNU General Public License as 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project published by the Free Software Foundation; either version 2 of the 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project License, or (at your option) any later version. 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project This program is distributed in the hope that it will be useful, but 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WITHOUT ANY WARRANTY; without even the implied warranty of 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project General Public License for more details. 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project You should have received a copy of the GNU General Public License 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project along with this program; if not, write to the Free Software 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 02111-1307, USA. 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project The GNU General Public License is contained in the file COPYING. 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/ 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* --------------------------------------------------------------------- 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU. 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project These functions are not called directly - they're the targets of code 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project redirection or load notifications (see pub_core_redir.h for info). 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project They're named weirdly so that the intercept code can find them when the 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shared object is initially loaded. 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Note that this filename has the "drd_" prefix because it can appear 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project in stack traces, and the "drd_" makes it a little clearer that it 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project originates from Valgrind. 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ------------------------------------------------------------------ */ 42bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Define _GNU_SOURCE to make sure that pthread_spinlock_t is available when 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * compiling with older glibc versions (2.3 or before). 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifndef _GNU_SOURCE 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define _GNU_SOURCE 49bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana#endif 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <assert.h> /* assert() */ 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <pthread.h> /* pthread_mutex_t */ 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <semaphore.h> /* sem_t */ 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> /* fprintf() */ 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h> /* malloc(), free() */ 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h> /* confstr() */ 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "config.h" /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP etc. */ 58bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana#include "drd_basics.h" /* DRD_() */ 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "drd_clientreq.h" 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "pub_tool_redir.h" /* VG_WRAP_FUNCTION_ZZ() */ 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* Defines. */ 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Do not undefine the two macro's below, or the following two subtle race 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * conditions will be introduced in the data race detection algorithm: 68bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana * - sg_init() runs on the context of the created thread and copies the 691c4027b68d5938795cc536c1d45e8d942ea537a4Daniel Lehmann * vector clock of the creator thread. This only works reliably if 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the creator thread waits until this copy has been performed. 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * - Since DRD_(thread_compute_minimum_vc)() does not take the vector 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clocks into account that are involved in thread creation but 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for which the corresponding thread has not yet been created, by 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * undefining the macro below it becomes possible that segments get 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * discarded that should not yet be discarded. Or: some data races 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * are not detected. 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define WAIT_UNTIL_CREATED_THREAD_STARTED 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define ALLOCATE_THREAD_ARGS_ON_THE_STACK 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Macro for generating a Valgrind interception function. 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param[in] ret_ty Return type of the function to be generated. 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param[in] zf Z-encoded name of the interception function. 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param[in] implf Name of the function that implements the intercept. 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param[in] arg_decl Argument declaration list enclosed in parentheses. 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param[in] argl Argument list enclosed in parentheses. 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define PTH_FUNC(ret_ty, zf, implf, argl_decl, argl) \ 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl; \ 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl \ 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { return implf argl; } 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Macro for generating three Valgrind interception functions: one with the 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Z-encoded name zf, one with ZAZa ("@*") appended to the name zf and one 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * with ZDZa ("$*") appended to the name zf. The second generated interception 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * function will intercept versioned symbols on Linux, and the third will 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * intercept versioned symbols on Darwin. 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define PTH_FUNCS(ret_ty, zf, implf, argl_decl, argl) \ 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PTH_FUNC(ret_ty, zf, implf, argl_decl, argl); \ 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PTH_FUNC(ret_ty, zf ## ZAZa, implf, argl_decl, argl); \ 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PTH_FUNC(ret_ty, zf ## ZDZa, implf, argl_decl, argl); 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Not inlining one of the intercept functions will cause the regression 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * tests to fail because this would cause an additional stackfram to appear 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the output. The __always_inline macro guarantees that inlining will 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * happen, even when compiling with optimization disabled. 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#undef __always_inline /* since already defined in <cdefs.h> */ 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if __GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 2 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define __always_inline __inline__ __attribute__((always_inline)) 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define __always_inline __inline__ 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* Local data structures. */ 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef struct 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* (*start)(void*); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* arg; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int detachstate; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if defined(WAIT_UNTIL_CREATED_THREAD_STARTED) 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int wrapper_started; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} DrdPosixThreadArgs; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* Local function declarations. */ 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void DRD_(init)(void) __attribute__((constructor)); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void DRD_(check_threading_library)(void); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void DRD_(set_main_thread_state)(void); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* Function definitions. */ 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Shared library initialization function. The function init() is called after 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * dlopen() has loaded the shared library with DRD client intercepts because 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the constructor attribute was specified in the declaration of this function. 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Note: do specify the -nostdlib option to gcc when linking this code into a 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * shared library because doing so would cancel the effect of the constructor 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * attribute ! Using the gcc option -nodefaultlibs is fine because this last 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * option preserves the shared library initialization code that calls 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * constructor and destructor functions. 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void DRD_(init)(void) 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DRD_(check_threading_library)(); 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DRD_(set_main_thread_state)(); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * POSIX threads and DRD each have their own mutex type identification. 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Convert POSIX threads' mutex type to DRD's mutex type. In the code below 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if-statements are used to test the value of 'kind' instead of a switch 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * statement because some of the PTHREAD_MUTEX_ macro's may have the same 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * value. 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic MutexT DRD_(pthread_to_drd_mutex_type)(const int kind) 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (kind == PTHREAD_MUTEX_RECURSIVE) 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mutex_type_recursive_mutex; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (kind == PTHREAD_MUTEX_ERRORCHECK) 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mutex_type_errorcheck_mutex; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (kind == PTHREAD_MUTEX_NORMAL) 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mutex_type_default_mutex; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (kind == PTHREAD_MUTEX_DEFAULT) 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mutex_type_default_mutex; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if defined(HAVE_PTHREAD_MUTEX_ADAPTIVE_NP) 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (kind == PTHREAD_MUTEX_ADAPTIVE_NP) 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mutex_type_default_mutex; 177bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana#endif 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mutex_type_invalid_mutex; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Read the mutex type stored in the client memory used for the mutex 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * implementation. 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @note This function depends on the implementation of the POSIX threads 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * library -- the POSIX standard does not define the name of the member in 190bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana * which the mutex type is stored. 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @note The function mutex_type() has been declared inline in order 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to avoid that it shows up in call stacks (drd/tests/...exp* files). 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @note glibc stores the mutex type in the lowest two bits, and uses the 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * higher bits for flags like PTHREAD_MUTEXATTR_FLAG_ROBUST and 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * PTHREAD_MUTEXATTR_FLAG_PSHARED. 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic __always_inline MutexT DRD_(mutex_type)(pthread_mutex_t* mutex) 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 199bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana#if defined(HAVE_PTHREAD_MUTEX_T__M_KIND) 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* glibc + LinuxThreads. */ 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int kind = mutex->__m_kind & 3; 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return DRD_(pthread_to_drd_mutex_type)(kind); 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#elif defined(HAVE_PTHREAD_MUTEX_T__DATA__KIND) 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* glibc + NPTL. */ 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int kind = mutex->__data.__kind & 3; 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return DRD_(pthread_to_drd_mutex_type)(kind); 207c74ee2f8d3a9f4ebd502c037623cdbaf664c28a9Mike Tsao#else 208c74ee2f8d3a9f4ebd502c037623cdbaf664c28a9Mike Tsao /* 209c74ee2f8d3a9f4ebd502c037623cdbaf664c28a9Mike Tsao * Another POSIX threads implementation. The mutex type won't be printed 210c74ee2f8d3a9f4ebd502c037623cdbaf664c28a9Mike Tsao * when enabling --trace-mutex=yes. 211c74ee2f8d3a9f4ebd502c037623cdbaf664c28a9Mike Tsao */ 212c74ee2f8d3a9f4ebd502c037623cdbaf664c28a9Mike Tsao return mutex_type_unknown; 213c74ee2f8d3a9f4ebd502c037623cdbaf664c28a9Mike Tsao#endif 214c74ee2f8d3a9f4ebd502c037623cdbaf664c28a9Mike Tsao} 215c74ee2f8d3a9f4ebd502c037623cdbaf664c28a9Mike Tsao 216c74ee2f8d3a9f4ebd502c037623cdbaf664c28a9Mike Tsao/** 217c74ee2f8d3a9f4ebd502c037623cdbaf664c28a9Mike Tsao * Tell DRD whether 'tid' is a joinable thread or a detached thread. 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void DRD_(set_joinable)(const pthread_t tid, const int joinable) 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int res; 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(joinable == 0 || joinable == 1); 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__SET_JOINABLE, 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tid, joinable, 0, 0, 0); 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** Tell DRD that the calling thread is about to enter pthread_create(). */ 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic __always_inline void DRD_(entering_pthread_create)(void) 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int res; 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__ENTERING_PTHREAD_CREATE, 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 0, 0, 0, 0, 0); 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** Tell DRD that the calling thread has left pthread_create(). */ 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic __always_inline void DRD_(left_pthread_create)(void) 237bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana{ 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int res; 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__LEFT_PTHREAD_CREATE, 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 0, 0, 0, 0, 0); 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 2441276b5f29ed6f889e9691cf296fd9911958895c1Steve Pomeroy * Entry point for newly created threads. This function is called from the 2451276b5f29ed6f889e9691cf296fd9911958895c1Steve Pomeroy * thread created by pthread_create(). 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void* DRD_(thread_wrapper)(void* arg) 2481276b5f29ed6f889e9691cf296fd9911958895c1Steve Pomeroy{ 2491276b5f29ed6f889e9691cf296fd9911958895c1Steve Pomeroy int res; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DrdPosixThreadArgs* arg_ptr; 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DrdPosixThreadArgs arg_copy; 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project arg_ptr = (DrdPosixThreadArgs*)arg; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project arg_copy = *arg_ptr; 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if defined(WAIT_UNTIL_CREATED_THREAD_STARTED) 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project arg_ptr->wrapper_started = 1; 257bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana#else 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if defined(ALLOCATE_THREAD_ARGS_ON_THE_STACK) 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#error Defining ALLOCATE_THREAD_ARGS_ON_THE_STACK but not \ 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WAIT_UNTIL_CREATED_THREAD_STARTED is not supported. 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free(arg_ptr); 2631c4027b68d5938795cc536c1d45e8d942ea537a4Daniel Lehmann#endif 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID, 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_self(), 0, 0, 0, 0); 268bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DRD_(set_joinable)(pthread_self(), 2701276b5f29ed6f889e9691cf296fd9911958895c1Steve Pomeroy arg_copy.detachstate == PTHREAD_CREATE_JOINABLE); 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (arg_copy.start)(arg_copy.arg); 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return 1 if the LinuxThreads implementation of POSIX Threads has been 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * detected, and 0 otherwise. 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see For more information about the confstr() function, see also 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.opengroup.org/onlinepubs/009695399/functions/confstr.html 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int DRD_(detected_linuxthreads)(void) 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if defined(linux) 285bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana#if defined(_CS_GNU_LIBPTHREAD_VERSION) 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Linux with a recent glibc. */ 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char buffer[256]; 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned len; 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len = confstr(_CS_GNU_LIBPTHREAD_VERSION, buffer, sizeof(buffer)); 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(len <= sizeof(buffer)); 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return len > 0 && buffer[0] == 'l'; 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 293bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana /* Linux without _CS_GNU_LIBPTHREAD_VERSION: most likely LinuxThreads. */ 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 2951276b5f29ed6f889e9691cf296fd9911958895c1Steve Pomeroy#endif 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Another OS than Linux, hence no LinuxThreads. */ 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Stop and print an error message in case a non-supported threading 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * library implementation (LinuxThreads) has been detected. 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void DRD_(check_threading_library)(void) 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DRD_(detected_linuxthreads)()) 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 310bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana if (getenv("LD_ASSUME_KERNEL")) 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project"Detected the LinuxThreads threading library. Sorry, but DRD only supports\n" 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project"the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n" 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project"after having unset the environment variable LD_ASSUME_KERNEL. Giving up.\n" 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project); 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 318bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana else 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 3201276b5f29ed6f889e9691cf296fd9911958895c1Steve Pomeroy fprintf(stderr, 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project"Detected the LinuxThreads threading library. Sorry, but DRD only supports\n" 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project"the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n" 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project"after having upgraded to a newer version of your Linux distribution.\n" 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project"Giving up.\n" 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project); 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project abort(); 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The main thread is the only thread not created by pthread_create(). 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Update DRD's state information about the main thread. 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 335bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintanastatic void DRD_(set_main_thread_state)(void) 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int res; 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Make sure that DRD knows about the main thread's POSIX thread ID. 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID, 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pthread_self(), 0, 0, 0, 0); 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 343bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana} 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3451276b5f29ed6f889e9691cf296fd9911958895c1Steve Pomeroy 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Note: as of today there exist three different versions of pthread_create 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in Linux: 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * - pthread_create@GLIBC_2.0 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * - pthread_create@@GLIBC_2.1 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * - pthread_create@@GLIBC_2.2.5 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * As an example, in libpthread-2.3.4 both pthread_create@GLIBC_2.0 and 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * pthread_create@@GLIBC_2.1 are defined, while in libpthread-2.9 all three 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * versions have been implemented. In any glibc version where more than one 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * pthread_create function has been implemented, older versions call the 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * newer versions. Or: the pthread_create* wrapper defined below can be 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called recursively. Any code in this wrapper should take this in account. 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * As an example, it is not safe to invoke the DRD_STOP_RECORDING 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / DRD_START_RECORDING client requests from the pthread_create wrapper. 360bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana * See also the implementation of pthread_create@GLIBC_2.0 in 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * glibc-2.9/nptl/pthread_create.c. 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic __always_inline 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint pthread_create_intercept(pthread_t* thread, const pthread_attr_t* attr, 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* (*start)(void*), void* arg) 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 368bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana int res; 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 3701276b5f29ed6f889e9691cf296fd9911958895c1Steve Pomeroy OrigFn fn; 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if defined(ALLOCATE_THREAD_ARGS_ON_THE_STACK) 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DrdPosixThreadArgs thread_args; 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DrdPosixThreadArgs* thread_args_p; 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project VALGRIND_GET_ORIG_FN(fn); 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if defined(ALLOCATE_THREAD_ARGS_ON_THE_STACK) 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thread_args_p = &thread_args; 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thread_args_p = malloc(sizeof(*thread_args_p)); 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(thread_args_p); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 385bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana thread_args_p->start = start; 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thread_args_p->arg = arg; 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if defined(WAIT_UNTIL_CREATED_THREAD_STARTED) 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DRD_IGNORE_VAR(thread_args_p->wrapper_started); 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thread_args_p->wrapper_started = 0; 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Find out whether the thread will be started as a joinable thread 393bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana * or as a detached thread. If no thread attributes have been specified, 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this means that the new thread will be started as a joinable thread. 3951276b5f29ed6f889e9691cf296fd9911958895c1Steve Pomeroy */ 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thread_args_p->detachstate = PTHREAD_CREATE_JOINABLE; 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (attr) 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pthread_attr_getdetachstate(attr, &thread_args_p->detachstate) != 0) 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(0); 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(thread_args_p->detachstate == PTHREAD_CREATE_JOINABLE 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || thread_args_p->detachstate == PTHREAD_CREATE_DETACHED); 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DRD_(entering_pthread_create)(); 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CALL_FN_W_WWWW(ret, fn, thread, attr, DRD_(thread_wrapper), thread_args_p); 410bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana DRD_(left_pthread_create)(); 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if defined(WAIT_UNTIL_CREATED_THREAD_STARTED) 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret == 0) 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Wait until the thread wrapper started. 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @todo Find out why some regression tests fail if thread arguments are 418bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana * passed via dynamically allocated memory and if the loop below is 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * removed. 4201276b5f29ed6f889e9691cf296fd9911958895c1Steve Pomeroy */ 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (! thread_args_p->wrapper_started) 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sched_yield(); 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if defined(ALLOCATE_THREAD_ARGS_DYNAMICALLY) 428794cf190aa38dffdad9e82fc86dbd94940b175b1Michael Wright free(thread_args_p); 429794cf190aa38dffdad9e82fc86dbd94940b175b1Michael Wright#endif 430794cf190aa38dffdad9e82fc86dbd94940b175b1Michael Wright 431794cf190aa38dffdad9e82fc86dbd94940b175b1Michael Wright#endif 432794cf190aa38dffdad9e82fc86dbd94940b175b1Michael Wright 433d208c3a68b96cf0c1dde5cdeab0e8464b9e52018Jeff Hamilton VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_START_NEW_SEGMENT, 434d208c3a68b96cf0c1dde5cdeab0e8464b9e52018Jeff Hamilton pthread_self(), 0, 0, 0, 0); 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 436bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana return ret; 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectPTH_FUNCS(int, pthreadZucreate, pthread_create_intercept, 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (pthread_t *thread, const pthread_attr_t *attr, 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void *(*start) (void *), void *arg), 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (thread, attr, start, arg)); 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic __always_inline 445bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintanaint pthread_join_intercept(pthread_t pt_joinee, void **thread_return) 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4471276b5f29ed6f889e9691cf296fd9911958895c1Steve Pomeroy int ret; 4481276b5f29ed6f889e9691cf296fd9911958895c1Steve Pomeroy int res; 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OrigFn fn; 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project VALGRIND_GET_ORIG_FN(fn); 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CALL_FN_W_WW(ret, fn, pt_joinee, thread_return); 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ret == 0) 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_THREAD_JOIN, 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pt_joinee, 0, 0, 0, 0); 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ret; 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 461bda8874a2990a864f32f8d2d916f7a05f33f797bFred QuintanaPTH_FUNCS(int, pthreadZujoin, pthread_join_intercept, 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (pthread_t pt_joinee, void **thread_return), 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (pt_joinee, thread_return)); 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic __always_inline 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint pthread_detach_intercept(pthread_t pt_thread) 467bda8874a2990a864f32f8d2d916f7a05f33f797bFred Quintana{ 468532abb65308725c649fe94ba485abc24ece05b2eVasu Nori int ret; 469532abb65308725c649fe94ba485abc24ece05b2eVasu Nori OrigFn fn; 470532abb65308725c649fe94ba485abc24ece05b2eVasu Nori VALGRIND_GET_ORIG_FN(fn); 471532abb65308725c649fe94ba485abc24ece05b2eVasu Nori { 472532abb65308725c649fe94ba485abc24ece05b2eVasu Nori CALL_FN_W_W(ret, fn, pt_thread); 473532abb65308725c649fe94ba485abc24ece05b2eVasu Nori if (ret == 0) 474532abb65308725c649fe94ba485abc24ece05b2eVasu Nori { 475532abb65308725c649fe94ba485abc24ece05b2eVasu Nori DRD_(set_joinable)(pt_thread, 0); 476532abb65308725c649fe94ba485abc24ece05b2eVasu Nori } 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ret; 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectPTH_FUNCS(int, pthreadZudetach, pthread_detach_intercept, 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (pthread_t thread), (thread)); 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// NOTE: be careful to intercept only pthread_cancel() and not 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// pthread_cancel_init() on Linux. 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic __always_inline 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint pthread_cancel_intercept(pthread_t pt_thread) 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int res; 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OrigFn fn; 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project VALGRIND_GET_ORIG_FN(fn); 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_THREAD_CANCEL, 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pt_thread, 0, 0, 0, 0); 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CALL_FN_W_W(ret, fn, pt_thread); 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_THREAD_CANCEL, 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pt_thread, ret==0, 0, 0, 0); 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ret; 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectPTH_FUNCS(int, pthreadZucancel, pthread_cancel_intercept, 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (pthread_t thread), (thread)) 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic __always_inline 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint pthread_once_intercept(pthread_once_t *once_control, 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void (*init_routine)(void)) 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OrigFn fn; 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project VALGRIND_GET_ORIG_FN(fn); 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Ignore any data races triggered by the implementation of pthread_once(). 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Necessary for Darwin. This is not necessary for Linux but doesn't have 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * any known adverse effects. 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DRD_IGNORE_VAR(*once_control); 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CALL_FN_W_WW(ret, fn, once_control, init_routine); 519f924a513da2ec1989a06dc16d007c0eca422ea67Jeff Hamilton DRD_STOP_IGNORING_VAR(*once_control); 520f924a513da2ec1989a06dc16d007c0eca422ea67Jeff Hamilton return ret; 521f924a513da2ec1989a06dc16d007c0eca422ea67Jeff Hamilton} 522f924a513da2ec1989a06dc16d007c0eca422ea67Jeff Hamilton 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectPTH_FUNCS(int, pthreadZuonce, pthread_once_intercept, 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (pthread_once_t *once_control, void (*init_routine)(void)), 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (once_control, init_routine)); 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic __always_inline 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint pthread_mutex_init_intercept(pthread_mutex_t *mutex, 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const pthread_mutexattr_t* attr) 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int res; 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OrigFn fn; 534 int mt; 535 VALGRIND_GET_ORIG_FN(fn); 536 mt = PTHREAD_MUTEX_DEFAULT; 537 if (attr) 538 pthread_mutexattr_gettype(attr, &mt); 539 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_INIT, 540 mutex, DRD_(pthread_to_drd_mutex_type)(mt), 541 0, 0, 0); 542 CALL_FN_W_WW(ret, fn, mutex, attr); 543 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_INIT, 544 mutex, 0, 0, 0, 0); 545 return ret; 546} 547 548PTH_FUNCS(int, pthreadZumutexZuinit, pthread_mutex_init_intercept, 549 (pthread_mutex_t *mutex, const pthread_mutexattr_t* attr), 550 (mutex, attr)); 551 552static __always_inline 553int pthread_mutex_destroy_intercept(pthread_mutex_t* mutex) 554{ 555 int ret; 556 int res; 557 OrigFn fn; 558 VALGRIND_GET_ORIG_FN(fn); 559 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_DESTROY, 560 mutex, 0, 0, 0, 0); 561 CALL_FN_W_W(ret, fn, mutex); 562 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY, 563 mutex, DRD_(mutex_type)(mutex), 0, 0, 0); 564 return ret; 565} 566 567PTH_FUNCS(int, pthreadZumutexZudestroy, pthread_mutex_destroy_intercept, 568 (pthread_mutex_t *mutex), (mutex)); 569 570static __always_inline 571int pthread_mutex_lock_intercept(pthread_mutex_t* mutex) 572{ 573 int ret; 574 int res; 575 OrigFn fn; 576 VALGRIND_GET_ORIG_FN(fn); 577 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK, 578 mutex, DRD_(mutex_type)(mutex), 0, 0, 0); 579 CALL_FN_W_W(ret, fn, mutex); 580 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__POST_MUTEX_LOCK, 581 mutex, ret == 0, 0, 0, 0); 582 return ret; 583} 584 585PTH_FUNCS(int, pthreadZumutexZulock, pthread_mutex_lock_intercept, 586 (pthread_mutex_t *mutex), (mutex)); 587 588static __always_inline 589int pthread_mutex_trylock_intercept(pthread_mutex_t* mutex) 590{ 591 int ret; 592 int res; 593 OrigFn fn; 594 VALGRIND_GET_ORIG_FN(fn); 595 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK, 596 mutex, DRD_(mutex_type)(mutex), 1, 0, 0); 597 CALL_FN_W_W(ret, fn, mutex); 598 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK, 599 mutex, ret == 0, 0, 0, 0); 600 return ret; 601} 602 603PTH_FUNCS(int, pthreadZumutexZutrylock, pthread_mutex_trylock_intercept, 604 (pthread_mutex_t *mutex), (mutex)); 605 606static __always_inline 607int pthread_mutex_timedlock_intercept(pthread_mutex_t *mutex, 608 const struct timespec *abs_timeout) 609{ 610 int ret; 611 int res; 612 OrigFn fn; 613 VALGRIND_GET_ORIG_FN(fn); 614 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK, 615 mutex, DRD_(mutex_type)(mutex), 0, 0, 0); 616 CALL_FN_W_WW(ret, fn, mutex, abs_timeout); 617 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK, 618 mutex, ret == 0, 0, 0, 0); 619 return ret; 620} 621 622PTH_FUNCS(int, pthreadZumutexZutimedlock, pthread_mutex_timedlock_intercept, 623 (pthread_mutex_t *mutex, const struct timespec *abs_timeout), 624 (mutex, abs_timeout)); 625 626static __always_inline 627int pthread_mutex_unlock_intercept(pthread_mutex_t *mutex) 628{ 629 int ret; 630 int res; 631 OrigFn fn; 632 VALGRIND_GET_ORIG_FN(fn); 633 VALGRIND_DO_CLIENT_REQUEST(res, -1, 634 VG_USERREQ__PRE_MUTEX_UNLOCK, 635 mutex, DRD_(mutex_type)(mutex), 0, 0, 0); 636 CALL_FN_W_W(ret, fn, mutex); 637 VALGRIND_DO_CLIENT_REQUEST(res, -1, 638 VG_USERREQ__POST_MUTEX_UNLOCK, 639 mutex, 0, 0, 0, 0); 640 return ret; 641} 642 643PTH_FUNCS(int, pthreadZumutexZuunlock, pthread_mutex_unlock_intercept, 644 (pthread_mutex_t *mutex), (mutex)); 645 646static __always_inline 647int pthread_cond_init_intercept(pthread_cond_t* cond, 648 const pthread_condattr_t* attr) 649{ 650 int ret; 651 int res; 652 OrigFn fn; 653 VALGRIND_GET_ORIG_FN(fn); 654 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_INIT, 655 cond, 0, 0, 0, 0); 656 CALL_FN_W_WW(ret, fn, cond, attr); 657 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_INIT, 658 cond, 0, 0, 0, 0); 659 return ret; 660} 661 662PTH_FUNCS(int, pthreadZucondZuinit, pthread_cond_init_intercept, 663 (pthread_cond_t* cond, const pthread_condattr_t* attr), 664 (cond, attr)); 665 666static __always_inline 667int pthread_cond_destroy_intercept(pthread_cond_t* cond) 668{ 669 int ret; 670 int res; 671 OrigFn fn; 672 VALGRIND_GET_ORIG_FN(fn); 673 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_DESTROY, 674 cond, 0, 0, 0, 0); 675 CALL_FN_W_W(ret, fn, cond); 676 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_DESTROY, 677 cond, 0, 0, 0, 0); 678 return ret; 679} 680 681PTH_FUNCS(int, pthreadZucondZudestroy, pthread_cond_destroy_intercept, 682 (pthread_cond_t* cond), (cond)); 683 684static __always_inline 685int pthread_cond_wait_intercept(pthread_cond_t *cond, pthread_mutex_t *mutex) 686{ 687 int ret; 688 int res; 689 OrigFn fn; 690 VALGRIND_GET_ORIG_FN(fn); 691 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_WAIT, 692 cond, mutex, DRD_(mutex_type)(mutex), 0, 0); 693 CALL_FN_W_WW(ret, fn, cond, mutex); 694 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_WAIT, 695 cond, mutex, 1, 0, 0); 696 return ret; 697} 698 699PTH_FUNCS(int, pthreadZucondZuwait, pthread_cond_wait_intercept, 700 (pthread_cond_t *cond, pthread_mutex_t *mutex), 701 (cond, mutex)); 702 703static __always_inline 704int pthread_cond_timedwait_intercept(pthread_cond_t *cond, 705 pthread_mutex_t *mutex, 706 const struct timespec* abstime) 707{ 708 int ret; 709 int res; 710 OrigFn fn; 711 VALGRIND_GET_ORIG_FN(fn); 712 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_WAIT, 713 cond, mutex, DRD_(mutex_type)(mutex), 0, 0); 714 CALL_FN_W_WWW(ret, fn, cond, mutex, abstime); 715 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_WAIT, 716 cond, mutex, 1, 0, 0); 717 return ret; 718} 719 720PTH_FUNCS(int, pthreadZucondZutimedwait, pthread_cond_timedwait_intercept, 721 (pthread_cond_t *cond, pthread_mutex_t *mutex, 722 const struct timespec* abstime), 723 (cond, mutex, abstime)); 724 725// NOTE: be careful to intercept only pthread_cond_signal() and not Darwin's 726// pthread_cond_signal_thread_np(). The former accepts one argument; the latter 727// two. Intercepting all pthread_cond_signal* functions will cause only one 728// argument to be passed to pthread_cond_signal_np() and hence will cause this 729// last function to crash. 730 731static __always_inline 732int pthread_cond_signal_intercept(pthread_cond_t* cond) 733{ 734 int ret; 735 int res; 736 OrigFn fn; 737 VALGRIND_GET_ORIG_FN(fn); 738 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_SIGNAL, 739 cond, 0, 0, 0, 0); 740 CALL_FN_W_W(ret, fn, cond); 741 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_SIGNAL, 742 cond, 0, 0, 0, 0); 743 return ret; 744} 745 746PTH_FUNCS(int, pthreadZucondZusignal, pthread_cond_signal_intercept, 747 (pthread_cond_t* cond), (cond)); 748 749static __always_inline 750int pthread_cond_broadcast_intercept(pthread_cond_t* cond) 751{ 752 int ret; 753 int res; 754 OrigFn fn; 755 VALGRIND_GET_ORIG_FN(fn); 756 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_BROADCAST, 757 cond, 0, 0, 0, 0); 758 CALL_FN_W_W(ret, fn, cond); 759 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_BROADCAST, 760 cond, 0, 0, 0, 0); 761 return ret; 762} 763 764PTH_FUNCS(int, pthreadZucondZubroadcast, pthread_cond_broadcast_intercept, 765 (pthread_cond_t* cond), (cond)); 766 767#if defined(HAVE_PTHREAD_SPIN_LOCK) 768static __always_inline 769int pthread_spin_init_intercept(pthread_spinlock_t *spinlock, int pshared) 770{ 771 int ret; 772 int res; 773 OrigFn fn; 774 VALGRIND_GET_ORIG_FN(fn); 775 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SPIN_INIT_OR_UNLOCK, 776 spinlock, 0, 0, 0, 0); 777 CALL_FN_W_WW(ret, fn, spinlock, pshared); 778 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SPIN_INIT_OR_UNLOCK, 779 spinlock, 0, 0, 0, 0); 780 return ret; 781} 782 783PTH_FUNCS(int, pthreadZuspinZuinit, pthread_spin_init_intercept, 784 (pthread_spinlock_t *spinlock, int pshared), (spinlock, pshared)); 785 786static __always_inline 787int pthread_spin_destroy_intercept(pthread_spinlock_t *spinlock) 788{ 789 int ret; 790 int res; 791 OrigFn fn; 792 VALGRIND_GET_ORIG_FN(fn); 793 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_DESTROY, 794 spinlock, 0, 0, 0, 0); 795 CALL_FN_W_W(ret, fn, spinlock); 796 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY, 797 spinlock, mutex_type_spinlock, 0, 0, 0); 798 return ret; 799} 800 801PTH_FUNCS(int, pthreadZuspinZudestroy, pthread_spin_destroy_intercept, 802 (pthread_spinlock_t *spinlock), (spinlock)); 803 804static __always_inline 805int pthread_spin_lock_intercept(pthread_spinlock_t *spinlock) 806{ 807 int ret; 808 int res; 809 OrigFn fn; 810 VALGRIND_GET_ORIG_FN(fn); 811 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK, 812 spinlock, mutex_type_spinlock, 0, 0, 0); 813 CALL_FN_W_W(ret, fn, spinlock); 814 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK, 815 spinlock, ret == 0, 0, 0, 0); 816 return ret; 817} 818 819PTH_FUNCS(int, pthreadZuspinZulock, pthread_spin_lock_intercept, 820 (pthread_spinlock_t *spinlock), (spinlock)); 821 822static __always_inline 823int pthread_spin_trylock_intercept(pthread_spinlock_t *spinlock) 824{ 825 int ret; 826 int res; 827 OrigFn fn; 828 VALGRIND_GET_ORIG_FN(fn); 829 VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK, 830 spinlock, mutex_type_spinlock, 0, 0, 0); 831 CALL_FN_W_W(ret, fn, spinlock); 832 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK, 833 spinlock, ret == 0, 0, 0, 0); 834 return ret; 835} 836 837PTH_FUNCS(int, pthreadZuspinZutrylock, pthread_spin_trylock_intercept, 838 (pthread_spinlock_t *spinlock), (spinlock)); 839 840static __always_inline 841int pthread_spin_unlock_intercept(pthread_spinlock_t *spinlock) 842{ 843 int ret; 844 int res; 845 OrigFn fn; 846 VALGRIND_GET_ORIG_FN(fn); 847 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SPIN_INIT_OR_UNLOCK, 848 spinlock, mutex_type_spinlock, 0, 0, 0); 849 CALL_FN_W_W(ret, fn, spinlock); 850 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SPIN_INIT_OR_UNLOCK, 851 spinlock, 0, 0, 0, 0); 852 return ret; 853} 854 855PTH_FUNCS(int, pthreadZuspinZuunlock, pthread_spin_unlock_intercept, 856 (pthread_spinlock_t *spinlock), (spinlock)); 857#endif // HAVE_PTHREAD_SPIN_LOCK 858 859 860#if defined(HAVE_PTHREAD_BARRIER_INIT) 861static __always_inline 862int pthread_barrier_init_intercept(pthread_barrier_t* barrier, 863 const pthread_barrierattr_t* attr, 864 unsigned count) 865{ 866 int ret; 867 int res; 868 OrigFn fn; 869 VALGRIND_GET_ORIG_FN(fn); 870 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_INIT, 871 barrier, pthread_barrier, count, 0, 0); 872 CALL_FN_W_WWW(ret, fn, barrier, attr, count); 873 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_INIT, 874 barrier, pthread_barrier, 0, 0, 0); 875 return ret; 876} 877 878PTH_FUNCS(int, pthreadZubarrierZuinit, pthread_barrier_init_intercept, 879 (pthread_barrier_t* barrier, const pthread_barrierattr_t* attr, 880 unsigned count), (barrier, attr, count)); 881 882static __always_inline 883int pthread_barrier_destroy_intercept(pthread_barrier_t* barrier) 884{ 885 int ret; 886 int res; 887 OrigFn fn; 888 VALGRIND_GET_ORIG_FN(fn); 889 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_DESTROY, 890 barrier, pthread_barrier, 0, 0, 0); 891 CALL_FN_W_W(ret, fn, barrier); 892 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_DESTROY, 893 barrier, pthread_barrier, 0, 0, 0); 894 return ret; 895} 896 897PTH_FUNCS(int, pthreadZubarrierZudestroy, pthread_barrier_destroy_intercept, 898 (pthread_barrier_t* barrier), (barrier)); 899 900static __always_inline 901int pthread_barrier_wait_intercept(pthread_barrier_t* barrier) 902{ 903 int ret; 904 int res; 905 OrigFn fn; 906 VALGRIND_GET_ORIG_FN(fn); 907 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_BARRIER_WAIT, 908 barrier, pthread_barrier, 0, 0, 0); 909 CALL_FN_W_W(ret, fn, barrier); 910 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_BARRIER_WAIT, 911 barrier, pthread_barrier, 912 ret == 0 || ret == PTHREAD_BARRIER_SERIAL_THREAD, 913 ret == PTHREAD_BARRIER_SERIAL_THREAD, 0); 914 return ret; 915} 916 917PTH_FUNCS(int, pthreadZubarrierZuwait, pthread_barrier_wait_intercept, 918 (pthread_barrier_t* barrier), (barrier)); 919#endif // HAVE_PTHREAD_BARRIER_INIT 920 921 922static __always_inline 923int sem_init_intercept(sem_t *sem, int pshared, unsigned int value) 924{ 925 int ret; 926 int res; 927 OrigFn fn; 928 VALGRIND_GET_ORIG_FN(fn); 929 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_INIT, 930 sem, pshared, value, 0, 0); 931 CALL_FN_W_WWW(ret, fn, sem, pshared, value); 932 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_INIT, 933 sem, 0, 0, 0, 0); 934 return ret; 935} 936 937PTH_FUNCS(int, semZuinit, sem_init_intercept, 938 (sem_t *sem, int pshared, unsigned int value), (sem, pshared, value)); 939 940static __always_inline 941int sem_destroy_intercept(sem_t *sem) 942{ 943 int ret; 944 int res; 945 OrigFn fn; 946 VALGRIND_GET_ORIG_FN(fn); 947 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_DESTROY, 948 sem, 0, 0, 0, 0); 949 CALL_FN_W_W(ret, fn, sem); 950 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_DESTROY, 951 sem, 0, 0, 0, 0); 952 return ret; 953} 954 955PTH_FUNCS(int, semZudestroy, sem_destroy_intercept, (sem_t *sem), (sem)); 956 957static __always_inline 958sem_t* sem_open_intercept(const char *name, int oflag, mode_t mode, 959 unsigned int value) 960{ 961 sem_t *ret; 962 int res; 963 OrigFn fn; 964 VALGRIND_GET_ORIG_FN(fn); 965 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_OPEN, 966 name, oflag, mode, value, 0); 967 CALL_FN_W_WWWW(ret, fn, name, oflag, mode, value); 968 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_OPEN, 969 ret != SEM_FAILED ? ret : 0, 970 name, oflag, mode, value); 971 return ret; 972} 973 974PTH_FUNCS(sem_t *, semZuopen, sem_open_intercept, 975 (const char *name, int oflag, mode_t mode, unsigned int value), 976 (name, oflag, mode, value)); 977 978static __always_inline int sem_close_intercept(sem_t *sem) 979{ 980 int ret; 981 int res; 982 OrigFn fn; 983 VALGRIND_GET_ORIG_FN(fn); 984 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_CLOSE, 985 sem, 0, 0, 0, 0); 986 CALL_FN_W_W(ret, fn, sem); 987 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_CLOSE, 988 sem, 0, 0, 0, 0); 989 return ret; 990} 991 992PTH_FUNCS(int, semZuclose, sem_close_intercept, (sem_t *sem), (sem)); 993 994static __always_inline int sem_wait_intercept(sem_t *sem) 995{ 996 int ret; 997 int res; 998 OrigFn fn; 999 VALGRIND_GET_ORIG_FN(fn); 1000 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT, 1001 sem, 0, 0, 0, 0); 1002 CALL_FN_W_W(ret, fn, sem); 1003 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT, 1004 sem, ret == 0, 0, 0, 0); 1005 return ret; 1006} 1007 1008PTH_FUNCS(int, semZuwait, sem_wait_intercept, (sem_t *sem), (sem)); 1009 1010static __always_inline int sem_trywait_intercept(sem_t *sem) 1011{ 1012 int ret; 1013 int res; 1014 OrigFn fn; 1015 VALGRIND_GET_ORIG_FN(fn); 1016 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT, 1017 sem, 0, 0, 0, 0); 1018 CALL_FN_W_W(ret, fn, sem); 1019 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT, 1020 sem, ret == 0, 0, 0, 0); 1021 return ret; 1022} 1023 1024PTH_FUNCS(int, semZutrywait, sem_trywait_intercept, (sem_t *sem), (sem)); 1025 1026static __always_inline 1027int sem_timedwait_intercept(sem_t *sem, const struct timespec *abs_timeout) 1028{ 1029 int ret; 1030 int res; 1031 OrigFn fn; 1032 VALGRIND_GET_ORIG_FN(fn); 1033 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_WAIT, 1034 sem, 0, 0, 0, 0); 1035 CALL_FN_W_WW(ret, fn, sem, abs_timeout); 1036 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_WAIT, 1037 sem, ret == 0, 0, 0, 0); 1038 return ret; 1039} 1040 1041PTH_FUNCS(int, semZutimedwait, sem_timedwait_intercept, 1042 (sem_t *sem, const struct timespec *abs_timeout), 1043 (sem, abs_timeout)); 1044 1045static __always_inline int sem_post_intercept(sem_t *sem) 1046{ 1047 int ret; 1048 int res; 1049 OrigFn fn; 1050 VALGRIND_GET_ORIG_FN(fn); 1051 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_POST, 1052 sem, 0, 0, 0, 0); 1053 CALL_FN_W_W(ret, fn, sem); 1054 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_POST, 1055 sem, ret == 0, 0, 0, 0); 1056 return ret; 1057} 1058 1059PTH_FUNCS(int, semZupost, sem_post_intercept, (sem_t *sem), (sem)); 1060 1061static __always_inline 1062int pthread_rwlock_init_intercept(pthread_rwlock_t* rwlock, 1063 const pthread_rwlockattr_t* attr) 1064{ 1065 int ret; 1066 int res; 1067 OrigFn fn; 1068 VALGRIND_GET_ORIG_FN(fn); 1069 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_INIT, 1070 rwlock, 0, 0, 0, 0); 1071 CALL_FN_W_WW(ret, fn, rwlock, attr); 1072 return ret; 1073} 1074 1075PTH_FUNCS(int, 1076 pthreadZurwlockZuinit, pthread_rwlock_init_intercept, 1077 (pthread_rwlock_t* rwlock, const pthread_rwlockattr_t* attr), 1078 (rwlock, attr)); 1079 1080static __always_inline 1081int pthread_rwlock_destroy_intercept(pthread_rwlock_t* rwlock) 1082{ 1083 int ret; 1084 int res; 1085 OrigFn fn; 1086 VALGRIND_GET_ORIG_FN(fn); 1087 CALL_FN_W_W(ret, fn, rwlock); 1088 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_DESTROY, 1089 rwlock, 0, 0, 0, 0); 1090 return ret; 1091} 1092 1093PTH_FUNCS(int, 1094 pthreadZurwlockZudestroy, pthread_rwlock_destroy_intercept, 1095 (pthread_rwlock_t* rwlock), (rwlock)); 1096 1097static __always_inline 1098int pthread_rwlock_rdlock_intercept(pthread_rwlock_t* rwlock) 1099{ 1100 int ret; 1101 int res; 1102 OrigFn fn; 1103 VALGRIND_GET_ORIG_FN(fn); 1104 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK, 1105 rwlock, 0, 0, 0, 0); 1106 CALL_FN_W_W(ret, fn, rwlock); 1107 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK, 1108 rwlock, ret == 0, 0, 0, 0); 1109 return ret; 1110} 1111 1112PTH_FUNCS(int, 1113 pthreadZurwlockZurdlock, pthread_rwlock_rdlock_intercept, 1114 (pthread_rwlock_t* rwlock), (rwlock)); 1115 1116static __always_inline 1117int pthread_rwlock_wrlock_intercept(pthread_rwlock_t* rwlock) 1118{ 1119 int ret; 1120 int res; 1121 OrigFn fn; 1122 VALGRIND_GET_ORIG_FN(fn); 1123 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK, 1124 rwlock, 0, 0, 0, 0); 1125 CALL_FN_W_W(ret, fn, rwlock); 1126 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK, 1127 rwlock, ret == 0, 0, 0, 0); 1128 return ret; 1129} 1130 1131PTH_FUNCS(int, 1132 pthreadZurwlockZuwrlock, pthread_rwlock_wrlock_intercept, 1133 (pthread_rwlock_t* rwlock), (rwlock)); 1134 1135static __always_inline 1136int pthread_rwlock_timedrdlock_intercept(pthread_rwlock_t* rwlock) 1137{ 1138 int ret; 1139 int res; 1140 OrigFn fn; 1141 VALGRIND_GET_ORIG_FN(fn); 1142 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK, 1143 rwlock, 0, 0, 0, 0); 1144 CALL_FN_W_W(ret, fn, rwlock); 1145 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK, 1146 rwlock, ret == 0, 0, 0, 0); 1147 return ret; 1148} 1149 1150PTH_FUNCS(int, 1151 pthreadZurwlockZutimedrdlock, pthread_rwlock_timedrdlock_intercept, 1152 (pthread_rwlock_t* rwlock), (rwlock)); 1153 1154static __always_inline 1155int pthread_rwlock_timedwrlock_intercept(pthread_rwlock_t* rwlock) 1156{ 1157 int ret; 1158 int res; 1159 OrigFn fn; 1160 VALGRIND_GET_ORIG_FN(fn); 1161 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK, 1162 rwlock, 0, 0, 0, 0); 1163 CALL_FN_W_W(ret, fn, rwlock); 1164 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK, 1165 rwlock, ret == 0, 0, 0, 0); 1166 return ret; 1167} 1168 1169PTH_FUNCS(int, 1170 pthreadZurwlockZutimedwrlock, pthread_rwlock_timedwrlock_intercept, 1171 (pthread_rwlock_t* rwlock), (rwlock)); 1172 1173static __always_inline 1174int pthread_rwlock_tryrdlock_intercept(pthread_rwlock_t* rwlock) 1175{ 1176 int ret; 1177 int res; 1178 OrigFn fn; 1179 VALGRIND_GET_ORIG_FN(fn); 1180 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_RDLOCK, 1181 rwlock, 0, 0, 0, 0); 1182 CALL_FN_W_W(ret, fn, rwlock); 1183 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_RDLOCK, 1184 rwlock, ret == 0, 0, 0, 0); 1185 return ret; 1186} 1187 1188PTH_FUNCS(int, 1189 pthreadZurwlockZutryrdlock, pthread_rwlock_tryrdlock_intercept, 1190 (pthread_rwlock_t* rwlock), (rwlock)); 1191 1192static __always_inline 1193int pthread_rwlock_trywrlock_intercept(pthread_rwlock_t* rwlock) 1194{ 1195 int ret; 1196 int res; 1197 OrigFn fn; 1198 VALGRIND_GET_ORIG_FN(fn); 1199 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_WRLOCK, 1200 rwlock, 0, 0, 0, 0); 1201 CALL_FN_W_W(ret, fn, rwlock); 1202 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_WRLOCK, 1203 rwlock, ret == 0, 0, 0, 0); 1204 return ret; 1205} 1206 1207PTH_FUNCS(int, 1208 pthreadZurwlockZutrywrlock, pthread_rwlock_trywrlock_intercept, 1209 (pthread_rwlock_t* rwlock), (rwlock)); 1210 1211static __always_inline 1212int pthread_rwlock_unlock_intercept(pthread_rwlock_t* rwlock) 1213{ 1214 int ret; 1215 int res; 1216 OrigFn fn; 1217 VALGRIND_GET_ORIG_FN(fn); 1218 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_RWLOCK_UNLOCK, 1219 rwlock, 0, 0, 0, 0); 1220 CALL_FN_W_W(ret, fn, rwlock); 1221 VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_RWLOCK_UNLOCK, 1222 rwlock, ret == 0, 0, 0, 0); 1223 return ret; 1224} 1225 1226PTH_FUNCS(int, 1227 pthreadZurwlockZuunlock, pthread_rwlock_unlock_intercept, 1228 (pthread_rwlock_t* rwlock), (rwlock)); 1229