1 #ifndef _TLSWRAPPER_HPP 2 #define _TLSWRAPPER_HPP 3 4 /* 5 * Copyright (c) 2021 The Khronos Group Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 * SPDX-License-Identifier: Apache-2.0 20 * 21 *//*! 22 * \file 23 * \brief Defines TLSContainer for CTS 24 */ 25 26 #include <mutex> 27 #include <thread> 28 29 template <class T> 30 class TLSContainer { 31 struct item { 32 std::thread::id owner; 33 T * p; 34 }; 35 std::mutex mutex; 36 std::vector<item> all; 37 public: find(bool remove)38 T * find(bool remove) { 39 T * r = nullptr; 40 std::thread::id tid = std::this_thread::get_id(); 41 mutex.lock(); 42 for(uint32_t i=0; i < all.size(); i++) { 43 if (all[i].owner == tid) { 44 r = all[i].p; 45 if (remove) { 46 all.erase(all.begin() + i); 47 } 48 break; 49 } 50 } 51 mutex.unlock(); 52 return r; 53 } 54 add(T * p)55 void add(T * p) { 56 item i; 57 i.owner = std::this_thread::get_id(); 58 i.p = p; 59 mutex.lock(); 60 all.push_back(i); 61 mutex.unlock(); 62 } TLSContainer()63 TLSContainer() {} ~TLSContainer()64 ~TLSContainer() {} 65 66 static TLSContainer<T> instance; 67 }; 68 69 template <class T> 70 class TLSWrapper 71 { 72 public: TLSWrapper()73 TLSWrapper() {} ~TLSWrapper()74 ~TLSWrapper() { 75 T * p = TLSContainer<T>::instance.find(true); 76 if (p) { 77 delete p; 78 } 79 } attach()80 T & attach() { 81 T * p = TLSContainer<T>::instance.find(false); 82 if (!p ){ 83 p = new T(); 84 TLSContainer<T>::instance.add(p); 85 } 86 return *p; 87 } 88 static thread_local TLSWrapper<T> instance; 89 }; 90 91 #define TLS_INSTANCE() \ 92 template<class T> TLSContainer<T> TLSContainer<T>::instance; \ 93 template<class T> thread_local TLSWrapper<T> TLSWrapper<T>::instance 94 95 #endif // _TLSWRAPPER_HPP 96