VirtualBox

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

Last change on this file since 28587 was 21337, checked in by vboxsync, 15 years ago

IPRT,HostDrv,AddDrv: Export public IPRT symbols for the linux kernel (pain).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.0 KB
Line 
1/* $Id: tls-generic.cpp 21337 2009-07-07 14:58:27Z 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#include <iprt/thread.h>
37#include "internal/iprt.h"
38
39#include <iprt/err.h>
40#include <iprt/asm.h>
41#include <iprt/log.h>
42#include <iprt/assert.h>
43#include "internal/thread.h"
44
45
46/*******************************************************************************
47* Global Variables *
48*******************************************************************************/
49/** Allocation bitmap. Set bits indicates allocated entries. */
50static uint32_t volatile g_au32AllocatedBitmap[(RTTHREAD_TLS_ENTRIES + 31) / 32];
51/** Destructors for each of the TLS entries. */
52static PFNRTTLSDTOR g_apfnDestructors[RTTHREAD_TLS_ENTRIES];
53
54
55RTR3DECL(RTTLS) RTTlsAlloc(void)
56{
57 RTTLS iTls;
58 int rc = RTTlsAllocEx(&iTls, NULL);
59 return RT_SUCCESS(rc) ? iTls : NIL_RTTLS;
60}
61
62
63RTR3DECL(int) RTTlsAllocEx(PRTTLS piTls, PFNRTTLSDTOR pfnDestructor)
64{
65 for (unsigned i = 0; i < 128; i++)
66 {
67 int iTls = ASMBitFirstClear(&g_au32AllocatedBitmap[0], RTTHREAD_TLS_ENTRIES);
68 if (iTls < 0)
69 {
70 *piTls = NIL_RTTLS;
71 return VERR_NO_MEMORY;
72 }
73 if (!ASMAtomicBitTestAndSet(&g_au32AllocatedBitmap[0], iTls))
74 {
75 g_apfnDestructors[iTls] = pfnDestructor;
76 *piTls = iTls;
77 return VINF_SUCCESS;
78 }
79 }
80
81 AssertFailed();
82 return VERR_NO_MEMORY;
83}
84
85
86RTR3DECL(int) RTTlsFree(RTTLS iTls)
87{
88 if (iTls == NIL_RTTLS)
89 return VINF_SUCCESS;
90 if ( iTls < 0
91 || iTls >= RTTHREAD_TLS_ENTRIES
92 || !ASMBitTest(&g_au32AllocatedBitmap[0], iTls))
93 return VERR_INVALID_PARAMETER;
94
95 ASMAtomicWritePtr((void * volatile *)&g_apfnDestructors[iTls], NULL);
96 rtThreadClearTlsEntry(iTls);
97 ASMAtomicBitClear(&g_au32AllocatedBitmap[0], iTls);
98 return VINF_SUCCESS;
99}
100
101
102RTR3DECL(void *) RTTlsGet(RTTLS iTls)
103{
104 void *pv;
105 int rc = RTTlsGetEx(iTls, &pv);
106 return RT_SUCCESS(rc) ? pv : NULL;
107}
108
109
110RTR3DECL(int) RTTlsGetEx(RTTLS iTls, void **ppvValue)
111{
112 if (RT_UNLIKELY( iTls < 0
113 || iTls >= RTTHREAD_TLS_ENTRIES
114 || !ASMBitTest(&g_au32AllocatedBitmap[0], iTls)))
115 return VERR_INVALID_PARAMETER;
116
117 PRTTHREADINT pThread = rtThreadGet(RTThreadSelf());
118 AssertReturn(pThread, VERR_NOT_SUPPORTED);
119 void *pv = pThread->apvTlsEntries[iTls];
120 rtThreadRelease(pThread);
121 *ppvValue = pv;
122 return VINF_SUCCESS;
123}
124
125
126RTR3DECL(int) RTTlsSet(RTTLS iTls, void *pvValue)
127{
128 if (RT_UNLIKELY( iTls < 0
129 || iTls >= RTTHREAD_TLS_ENTRIES
130 || !ASMBitTest(&g_au32AllocatedBitmap[0], iTls)))
131 return VERR_INVALID_PARAMETER;
132
133 PRTTHREADINT pThread = rtThreadGet(RTThreadSelf());
134 AssertReturn(pThread, VERR_NOT_SUPPORTED);
135 pThread->apvTlsEntries[iTls] = pvValue;
136 rtThreadRelease(pThread);
137 return VINF_SUCCESS;
138}
139
140
141
142/**
143 * Called at thread termination to invoke TLS destructors.
144 *
145 * @param pThread The current thread.
146 */
147void rtThreadTlsDestruction(PRTTHREADINT pThread)
148{
149 for (RTTLS iTls = 0; iTls < RTTHREAD_TLS_ENTRIES; iTls++)
150 {
151 void *pv = pThread->apvTlsEntries[iTls];
152 if (pv)
153 {
154 PFNRTTLSDTOR pfnDestructor = (PFNRTTLSDTOR)(uintptr_t)ASMAtomicUoReadPtr((void * volatile *)(uintptr_t)&g_apfnDestructors[iTls]);
155 if (pfnDestructor)
156 {
157 pThread->apvTlsEntries[iTls] = NULL;
158 pfnDestructor(pv);
159 }
160 }
161 }
162}
163
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