1b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea/* 2b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * Copyright (C) 2012 The Android Open Source Project 3b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * All rights reserved. 4b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * 5b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * Redistribution and use in source and binary forms, with or without 6b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * modification, are permitted provided that the following conditions 7b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * are met: 8b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * * Redistributions of source code must retain the above copyright 9b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * notice, this list of conditions and the following disclaimer. 10b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * * Redistributions in binary form must reproduce the above copyright 11b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * notice, this list of conditions and the following disclaimer in 12b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * the documentation and/or other materials provided with the 13b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * distribution. 14b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * 15b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea * SUCH DAMAGE. 27b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea */ 28b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea 29b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea#ifndef _BIONIC_THREAD_LOCAL_BUFFER_H_included 30b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea#define _BIONIC_THREAD_LOCAL_BUFFER_H_included 31b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea 32b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea#include <malloc.h> 33b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea#include <pthread.h> 34b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea 356170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes// TODO: use __thread instead? 366170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes 376170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughestemplate <typename T, size_t Size = sizeof(T)> 386170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughesclass ThreadLocalBuffer { 396170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes public: 406170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes ThreadLocalBuffer() { 416170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes // We used to use pthread_once to initialize the keys, but life is more predictable 426170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes // if we allocate them all up front when the C library starts up, via __constructor__. 436170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes pthread_key_create(&key_, free); 446170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes } 456170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes 466170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes T* get() { 476170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes T* result = reinterpret_cast<T*>(pthread_getspecific(key_)); 486170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes if (result == nullptr) { 496170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes result = reinterpret_cast<T*>(calloc(1, Size)); 506170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes pthread_setspecific(key_, result); 516170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes } 526170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes return result; 534a2891d8c8f09a64ea9e1479518b0cc969bd5969Yabin Cui } 543e898476c7230b60a0f76968e64ff25f475b48c0Elliott Hughes 556170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes size_t size() { return Size; } 566170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes 576170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes private: 586170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes pthread_key_t key_; 596170693e28dd72a1517c267f3f62b3f37477b8bbElliott Hughes}; 60b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea 61b5f053b5a7deb084e7a052d527e0aa41339ae05cIrina Tirdea#endif // _BIONIC_THREAD_LOCAL_BUFFER_H_included 62