VirtualBox

source: vbox/trunk/src/VBox/Runtime/generic/tls-generic.cpp@ 19167

Last change on this file since 19167 was 8245, checked in by vboxsync, 17 years ago

rebranding: IPRT files again.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.9 KB
Line 
1/* $Id: tls-generic.cpp 8245 2008-04-21 17:24:28Z vboxsync $ */
2/** @file
3 * IPRT - Thread Local Storage (TSL), Generic Implementation.
4 */
5
6/*
7 * Copyright (C) 2008 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 *
26 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31
32/*******************************************************************************
33* Header Files *
34*******************************************************************************/
35#define LOG_GROUP RTLOGGROUP_THREAD
36
37#include <iprt/thread.h>
38#include <iprt/err.h>
39#include <iprt/asm.h>
40#include <iprt/log.h>
41#include <iprt/assert.h>
42#include "internal/thread.h"
43
44
45/*******************************************************************************
46* Global Variables *
47*******************************************************************************/
48/** Allocation bitmap. Set bits indicates allocated entries. */
49static uint32_t volatile g_au32AllocatedBitmap[(RTTHREAD_TLS_ENTRIES + 31) / 32];
50/** Destructors for each of the TLS entries. */
51static PFNRTTLSDTOR g_apfnDestructors[RTTHREAD_TLS_ENTRIES];
52
53
54RTR3DECL(RTTLS) RTTlsAlloc(void)
55{
56 RTTLS iTls;
57 int rc = RTTlsAllocEx(&iTls, NULL);
58 return RT_SUCCESS(rc) ? iTls : NIL_RTTLS;
59}
60
61
62RTR3DECL(int) RTTlsAllocEx(PRTTLS piTls, PFNRTTLSDTOR pfnDestructor)
63{
64 for (unsigned i = 0; i < 128; i++)
65 {
66 int iTls = ASMBitFirstClear(&g_au32AllocatedBitmap[0], RTTHREAD_TLS_ENTRIES);
67 if (iTls < 0)
68 {
69 *piTls = NIL_RTTLS;
70 return VERR_NO_MEMORY;
71 }
72 if (!ASMAtomicBitTestAndSet(&g_au32AllocatedBitmap[0], iTls))
73 {
74 g_apfnDestructors[iTls] = pfnDestructor;
75 *piTls = iTls;
76 return VINF_SUCCESS;
77 }
78 }
79
80 AssertFailed();
81 return VERR_NO_MEMORY;
82}
83
84
85RTR3DECL(int) RTTlsFree(RTTLS iTls)
86{
87 if (iTls == NIL_RTTLS)
88 return VINF_SUCCESS;
89 if ( iTls < 0
90 || iTls >= RTTHREAD_TLS_ENTRIES
91 || !ASMBitTest(&g_au32AllocatedBitmap[0], iTls))
92 return VERR_INVALID_PARAMETER;
93
94 ASMAtomicWritePtr((void * volatile *)&g_apfnDestructors[iTls], NULL);
95 rtThreadClearTlsEntry(iTls);
96 ASMAtomicBitClear(&g_au32AllocatedBitmap[0], iTls);
97 return VINF_SUCCESS;
98}
99
100
101RTR3DECL(void *) RTTlsGet(RTTLS iTls)
102{
103 void *pv;
104 int rc = RTTlsGetEx(iTls, &pv);
105 return RT_SUCCESS(rc) ? pv : NULL;
106}
107
108
109RTR3DECL(int) RTTlsGetEx(RTTLS iTls, void **ppvValue)
110{
111 if (RT_UNLIKELY( iTls < 0
112 || iTls >= RTTHREAD_TLS_ENTRIES
113 || !ASMBitTest(&g_au32AllocatedBitmap[0], iTls)))
114 return VERR_INVALID_PARAMETER;
115
116 PRTTHREADINT pThread = rtThreadGet(RTThreadSelf());
117 AssertReturn(pThread, VERR_NOT_SUPPORTED);
118 void *pv = pThread->apvTlsEntries[iTls];
119 rtThreadRelease(pThread);
120 *ppvValue = pv;
121 return VINF_SUCCESS;
122}
123
124
125RTR3DECL(int) RTTlsSet(RTTLS iTls, void *pvValue)
126{
127 if (RT_UNLIKELY( iTls < 0
128 || iTls >= RTTHREAD_TLS_ENTRIES
129 || !ASMBitTest(&g_au32AllocatedBitmap[0], iTls)))
130 return VERR_INVALID_PARAMETER;
131
132 PRTTHREADINT pThread = rtThreadGet(RTThreadSelf());
133 AssertReturn(pThread, VERR_NOT_SUPPORTED);
134 pThread->apvTlsEntries[iTls] = pvValue;
135 rtThreadRelease(pThread);
136 return VINF_SUCCESS;
137}
138
139
140
141/**
142 * Called at thread termination to invoke TLS destructors.
143 *
144 * @param pThread The current thread.
145 */
146void rtThreadTlsDestruction(PRTTHREADINT pThread)
147{
148 for (RTTLS iTls = 0; iTls < RTTHREAD_TLS_ENTRIES; iTls++)
149 {
150 void *pv = pThread->apvTlsEntries[iTls];
151 if (pv)
152 {
153 PFNRTTLSDTOR pfnDestructor = (PFNRTTLSDTOR)(uintptr_t)ASMAtomicUoReadPtr((void * volatile *)(uintptr_t)&g_apfnDestructors[iTls]);
154 if (pfnDestructor)
155 {
156 pThread->apvTlsEntries[iTls] = NULL;
157 pfnDestructor(pv);
158 }
159 }
160 }
161}
162
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette