1 /*------------------------------------------------------------------------- 2 * drawElements Thread Library 3 * --------------------------- 4 * 5 * Copyright 2014 The Android Open Source Project 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 *//*! 20 * \file 21 * \brief Thread-safe singleton. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "deSingleton.h" 25 #include "deAtomic.h" 26 #include "deThread.h" 27 28 DE_STATIC_ASSERT(sizeof(deSingletonState) == sizeof(deUint32)); 29 30 void deInitSingleton (volatile deSingletonState* singletonState, deSingletonConstructorFunc constructor, void* arg) 31 { 32 if (*singletonState != DE_SINGLETON_STATE_INITIALIZED) 33 { 34 deSingletonState curState = (deSingletonState)deAtomicCompareExchange32((volatile deUint32*)singletonState, (deUint32)DE_SINGLETON_STATE_NOT_INITIALIZED, (deUint32)DE_SINGLETON_STATE_INITIALIZING); 35 36 if (curState == DE_SINGLETON_STATE_NOT_INITIALIZED) 37 { 38 constructor(arg); 39 40 deMemoryReadWriteFence(); 41 42 *singletonState = DE_SINGLETON_STATE_INITIALIZED; 43 44 deMemoryReadWriteFence(); 45 } 46 else if (curState == DE_SINGLETON_STATE_INITIALIZING) 47 { 48 for (;;) 49 { 50 deMemoryReadWriteFence(); 51 52 if (*singletonState == DE_SINGLETON_STATE_INITIALIZED) 53 break; 54 else 55 deYield(); 56 } 57 } 58 59 DE_ASSERT(*singletonState == DE_SINGLETON_STATE_INITIALIZED); 60 } 61 } 62