Home | History | Annotate | Download | only in testing
      1 // Copyright (c) 2012, Google Inc.
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are
      6 // met:
      7 //
      8 //     * Redistributions of source code must retain the above copyright
      9 // notice, this list of conditions and the following disclaimer.
     10 //     * Redistributions in binary form must reproduce the above
     11 // copyright notice, this list of conditions and the following disclaimer
     12 // in the documentation and/or other materials provided with the
     13 // distribution.
     14 //     * Neither the name of Google Inc. nor the names of its
     15 // contributors may be used to endorse or promote products derived from
     16 // this software without specific prior written permission.
     17 //
     18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 
     30 // This contains Pthread-related functions not provided by the Android NDK
     31 // but required by the Breakpad unit test. The functions are inlined here
     32 // in a C++ anonymous namespace in order to keep the build files simples.
     33 
     34 #ifndef GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_PTHREAD_FIXES_H
     35 #define GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_PTHREAD_FIXES_H
     36 
     37 #include <pthread.h>
     38 
     39 namespace {
     40 
     41 // Android doesn't provide pthread_barrier_t for now.
     42 #ifndef PTHREAD_BARRIER_SERIAL_THREAD
     43 
     44 // Anything except 0 will do here.
     45 #define PTHREAD_BARRIER_SERIAL_THREAD  0x12345
     46 
     47 typedef struct {
     48   pthread_mutex_t  mutex;
     49   pthread_cond_t   cond;
     50   unsigned         count;
     51 } pthread_barrier_t;
     52 
     53 int pthread_barrier_init(pthread_barrier_t* barrier,
     54                          const void* /* barrier_attr */,
     55                          unsigned count) {
     56   barrier->count = count;
     57   pthread_mutex_init(&barrier->mutex, NULL);
     58   pthread_cond_init(&barrier->cond, NULL);
     59   return 0;
     60 }
     61 
     62 int pthread_barrier_wait(pthread_barrier_t* barrier) {
     63   // Lock the mutex
     64   pthread_mutex_lock(&barrier->mutex);
     65   // Decrement the count. If this is the first thread to reach 0, wake up
     66   // waiters, unlock the mutex, then return PTHREAD_BARRIER_SERIAL_THREAD.
     67   if (--barrier->count == 0) {
     68     // First thread to reach the barrier
     69     pthread_cond_broadcast(&barrier->cond);
     70     pthread_mutex_unlock(&barrier->mutex);
     71     return PTHREAD_BARRIER_SERIAL_THREAD;
     72   }
     73   // Otherwise, wait for other threads until the count reaches 0, then
     74   // return 0 to indicate this is not the first thread.
     75   do {
     76     pthread_cond_wait(&barrier->cond, &barrier->mutex);
     77   } while (barrier->count > 0);
     78 
     79   pthread_mutex_unlock(&barrier->mutex);
     80   return 0;
     81 }
     82 
     83 int pthread_barrier_destroy(pthread_barrier_t *barrier) {
     84   barrier->count = 0;
     85   pthread_cond_destroy(&barrier->cond);
     86   pthread_mutex_destroy(&barrier->mutex);
     87   return 0;
     88 }
     89 
     90 #endif  // defined(PTHREAD_BARRIER_SERIAL_THREAD)
     91 
     92 int pthread_yield(void) {
     93   sched_yield();
     94   return 0;
     95 }
     96 
     97 }  // namespace
     98 
     99 #endif  // GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_PTHREAD_FIXES_H
    100