00001 // Copyright (c) 2005, Google Inc. 00002 // All rights reserved. 00003 // 00004 // Redistribution and use in source and binary forms, with or without 00005 // modification, are permitted provided that the following conditions are 00006 // met: 00007 // 00008 // * Redistributions of source code must retain the above copyright 00009 // notice, this list of conditions and the following disclaimer. 00010 // * Redistributions in binary form must reproduce the above 00011 // copyright notice, this list of conditions and the following disclaimer 00012 // in the documentation and/or other materials provided with the 00013 // distribution. 00014 // * Neither the name of Google Inc. nor the names of its 00015 // contributors may be used to endorse or promote products derived from 00016 // this software without specific prior written permission. 00017 // 00018 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00019 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00020 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00021 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00022 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00023 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00024 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00025 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00026 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00027 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00028 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 00030 // --- 00031 // Author: Paul Menage <opensource@google.com> 00032 00033 //------------------------------------------------------------------- 00034 // Some wrappers for pthread functions so that we can be LD_PRELOADed 00035 // against non-pthreads apps. 00036 //------------------------------------------------------------------- 00037 00038 #include "config.h" 00039 #include <assert.h> 00040 #include <pthread.h> 00041 // We don't actually need strings. But including this header seems to 00042 // stop the compiler trying to short-circuit our pthreads existence 00043 // tests and claiming that the address of a function is always 00044 // non-zero. I have no idea why ... 00045 #include <string> 00046 #include "maybe_threads.h" 00047 00048 #define MAX_PERTHREAD_VALS 16 00049 static void *perftools_pthread_specific_vals[MAX_PERTHREAD_VALS]; 00050 static pthread_key_t next_key; 00051 00052 // This module will behave very strangely if some pthreads functions 00053 // exist and others don't 00054 00055 int perftools_pthread_key_create(pthread_key_t *key, 00056 void (*destr_function) (void *)) { 00057 if (pthread_key_create) { 00058 return pthread_key_create(key, destr_function); 00059 } else { 00060 assert(next_key < MAX_PERTHREAD_VALS); 00061 *key = next_key++; 00062 return 0; 00063 } 00064 } 00065 00066 void *perftools_pthread_getspecific(pthread_key_t key) { 00067 if (pthread_getspecific) { 00068 return pthread_getspecific(key); 00069 } else { 00070 return perftools_pthread_specific_vals[key]; 00071 } 00072 } 00073 00074 int perftools_pthread_setspecific(pthread_key_t key, void *val) { 00075 if (pthread_setspecific) { 00076 return pthread_setspecific(key, val); 00077 } else { 00078 perftools_pthread_specific_vals[key] = val; 00079 return 0; 00080 } 00081 } 00082 00083 int perftools_pthread_once(pthread_once_t *ctl, 00084 void (*init_routine) (void)) { 00085 if (pthread_once) { 00086 return pthread_once(ctl, init_routine); 00087 } else { 00088 #if defined(__FreeBSD__) || defined(__APPLE__) 00089 abort(); 00090 #else 00091 if (*ctl == PTHREAD_ONCE_INIT) { 00092 init_routine(); 00093 *ctl = 1; 00094 } 00095 return 0; 00096 #endif 00097 } 00098 }