1fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui/* 2fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * Copyright (C) 2015 The Android Open Source Project 3fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * All rights reserved. 4fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * 5fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * Redistribution and use in source and binary forms, with or without 6fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * modification, are permitted provided that the following conditions 7fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * are met: 8fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * * Redistributions of source code must retain the above copyright 9fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * notice, this list of conditions and the following disclaimer. 10fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * * Redistributions in binary form must reproduce the above copyright 11fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * notice, this list of conditions and the following disclaimer in 12fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * the documentation and/or other materials provided with the 13fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * distribution. 14fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * 15fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui * SUCH DAMAGE. 27fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui */ 28fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui#include <pthread.h> 29fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui 30fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui#include "private/bionic_lock.h" 31fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui 32fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui// User-level spinlocks can be hazardous to battery life on Android. 33fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui// We implement a simple compromise that behaves mostly like a spinlock, 34fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui// but prevents excessively long spinning. 35fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui 36fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cuistruct pthread_spinlock_internal_t { 37fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui Lock lock; 38fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui}; 39fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui 40fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cuistatic_assert(sizeof(pthread_spinlock_t) == sizeof(pthread_spinlock_internal_t), 41fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui "pthread_spinlock_t should actually be pthread_spinlock_internal_t."); 42fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui 43fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cuistatic_assert(alignof(pthread_spinlock_t) >= 4, 44fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui "pthread_spinlock_t should fulfill the alignment of pthread_spinlock_internal_t."); 45fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui 46fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cuistatic inline pthread_spinlock_internal_t* __get_internal_spinlock(pthread_spinlock_t* lock) { 47fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui return reinterpret_cast<pthread_spinlock_internal_t*>(lock); 48fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui} 49fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui 50fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cuiint pthread_spin_init(pthread_spinlock_t* lock_interface, int pshared) { 51fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui pthread_spinlock_internal_t* lock = __get_internal_spinlock(lock_interface); 52fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui lock->lock.init(pshared); 53fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui return 0; 54fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui} 55fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui 56fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cuiint pthread_spin_destroy(pthread_spinlock_t* lock_interface) { 57fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui pthread_spinlock_internal_t* lock = __get_internal_spinlock(lock_interface); 58fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui return lock->lock.trylock() ? 0 : EBUSY; 59fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui} 60fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui 61fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cuiint pthread_spin_trylock(pthread_spinlock_t* lock_interface) { 62fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui pthread_spinlock_internal_t* lock = __get_internal_spinlock(lock_interface); 63fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui return lock->lock.trylock() ? 0 : EBUSY; 64fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui} 65fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui 66fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cuiint pthread_spin_lock(pthread_spinlock_t* lock_interface) { 67fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui pthread_spinlock_internal_t* lock = __get_internal_spinlock(lock_interface); 68fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui for (int i = 0; i < 10000; ++i) { 69fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui if (lock->lock.trylock()) { 70fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui return 0; 71fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui } 72fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui } 73fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui lock->lock.lock(); 74fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui return 0; 75fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui} 76fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui 77fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cuiint pthread_spin_unlock(pthread_spinlock_t* lock_interface) { 78fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui pthread_spinlock_internal_t* lock = __get_internal_spinlock(lock_interface); 79fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui lock->lock.unlock(); 80fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui return 0; 81fe3a83a9343f0e4ff654f09ef8ffc8a773c7c105Yabin Cui} 82