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 Unix implementation of thread-local storage.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "deThreadLocal.h"
25 
26 #if (DE_OS == DE_OS_UNIX || DE_OS == DE_OS_OSX || DE_OS == DE_OS_ANDROID || DE_OS == DE_OS_SYMBIAN || DE_OS == DE_OS_IOS)
27 
28 #if !defined(_XOPEN_SOURCE) || (_XOPEN_SOURCE < 500)
29 #	error You are using too old posix API!
30 #endif
31 
32 #include <pthread.h>
33 
34 DE_STATIC_ASSERT(sizeof(pthread_key_t) <= sizeof(deThreadLocal));
35 
36 /* \note 0 is valid pthread_key_t, but not valid for deThreadLocal */
37 
keyToThreadLocal(pthread_key_t key)38 DE_INLINE deThreadLocal keyToThreadLocal (pthread_key_t key)
39 {
40 	return (deThreadLocal)(key + 1);
41 }
42 
threadLocalToKey(deThreadLocal threadLocal)43 DE_INLINE pthread_key_t threadLocalToKey (deThreadLocal threadLocal)
44 {
45 	DE_ASSERT(threadLocal != 0);
46 	return (pthread_key_t)(threadLocal - 1);
47 }
48 
deThreadLocal_create(void)49 deThreadLocal deThreadLocal_create (void)
50 {
51 	pthread_key_t key = (pthread_key_t)0;
52 	if (pthread_key_create(&key, DE_NULL) != 0)
53 		return 0;
54 	return keyToThreadLocal(key);
55 }
56 
deThreadLocal_destroy(deThreadLocal threadLocal)57 void deThreadLocal_destroy (deThreadLocal threadLocal)
58 {
59 	int ret = 0;
60 	ret = pthread_key_delete(threadLocalToKey(threadLocal));
61 	DE_ASSERT(ret == 0);
62 	DE_UNREF(ret);
63 }
64 
deThreadLocal_get(deThreadLocal threadLocal)65 void* deThreadLocal_get (deThreadLocal threadLocal)
66 {
67 	return pthread_getspecific(threadLocalToKey(threadLocal));
68 }
69 
deThreadLocal_set(deThreadLocal threadLocal,void * value)70 void deThreadLocal_set (deThreadLocal threadLocal, void* value)
71 {
72 	int ret = 0;
73 	ret = pthread_setspecific(threadLocalToKey(threadLocal), value);
74 	DE_ASSERT(ret == 0);
75 	DE_UNREF(ret);
76 }
77 
78 #endif /* DE_OS */
79