VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/os2/thread-os2.cpp@ 16311

Last change on this file since 16311 was 16311, checked in by vboxsync, 16 years ago

IPRT: Changed the RTTLS type and corrected RTTLSAlloc defintions.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.2 KB
Line 
1/* $Id: thread-os2.cpp 16311 2009-01-28 13:46:41Z vboxsync $ */
2/** @file
3 * IPRT - Threads, OS/2.
4 */
5
6/*
7 * Copyright (C) 2006-2007 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#define INCL_BASE
37#include <os2.h>
38#undef RT_MAX
39
40#include <errno.h>
41#include <process.h>
42#include <stdlib.h>
43#include <signal.h>
44#include <InnoTekLIBC/FastInfoBlocks.h>
45#include <InnoTekLIBC/thread.h>
46
47#include <iprt/thread.h>
48#include <iprt/log.h>
49#include <iprt/assert.h>
50#include <iprt/alloc.h>
51#include <iprt/asm.h>
52#include <iprt/string.h>
53#include <iprt/err.h>
54#include "internal/thread.h"
55
56
57/*******************************************************************************
58* Global Variables *
59*******************************************************************************/
60/** Pointer to thread local memory which points to the current thread. */
61static PRTTHREADINT *g_ppCurThread;
62
63
64/*******************************************************************************
65* Internal Functions *
66*******************************************************************************/
67static void rtThreadNativeMain(void *pvArgs);
68
69
70int rtThreadNativeInit(void)
71{
72 /*
73 * Allocate thread local memory.
74 */
75 PULONG pul;
76 int rc = DosAllocThreadLocalMemory(1, &pul);
77 if (rc)
78 return VERR_NO_TLS_FOR_SELF;
79 g_ppCurThread = (PRTTHREADINT *)(void *)pul;
80 return VINF_SUCCESS;
81}
82
83
84int rtThreadNativeAdopt(PRTTHREADINT pThread)
85{
86 /*
87 * Block SIGALRM - required for timer-posix.cpp.
88 * This is done to limit harm done by OSes which doesn't do special SIGALRM scheduling.
89 * It will not help much if someone creates threads directly using pthread_create. :/
90 */
91 sigset_t SigSet;
92 sigemptyset(&SigSet);
93 sigaddset(&SigSet, SIGALRM);
94 sigprocmask(SIG_BLOCK, &SigSet, NULL);
95
96 *g_ppCurThread = pThread;
97 return VINF_SUCCESS;
98}
99
100
101/**
102 * Wrapper which unpacks the params and calls thread function.
103 */
104static void rtThreadNativeMain(void *pvArgs)
105{
106 /*
107 * Block SIGALRM - required for timer-posix.cpp.
108 * This is done to limit harm done by OSes which doesn't do special SIGALRM scheduling.
109 * It will not help much if someone creates threads directly using pthread_create. :/
110 */
111 sigset_t SigSet;
112 sigemptyset(&SigSet);
113 sigaddset(&SigSet, SIGALRM);
114 sigprocmask(SIG_BLOCK, &SigSet, NULL);
115
116 /*
117 * Call common main.
118 */
119 PRTTHREADINT pThread = (PRTTHREADINT)pvArgs;
120 *g_ppCurThread = pThread;
121
122#ifdef fibGetTidPid
123 rtThreadMain(pThread, fibGetTidPid(), &pThread->szName[0]);
124#else
125 rtThreadMain(pThread, _gettid(), &pThread->szName[0]);
126#endif
127
128 *g_ppCurThread = NULL;
129 _endthread();
130}
131
132
133int rtThreadNativeCreate(PRTTHREADINT pThread, PRTNATIVETHREAD pNativeThread)
134{
135 /*
136 * Default stack size.
137 */
138 if (!pThread->cbStack)
139 pThread->cbStack = 512*1024;
140
141 /*
142 * Create the thread.
143 */
144 int iThreadId = _beginthread(rtThreadNativeMain, NULL, pThread->cbStack, pThread);
145 if (iThreadId > 0)
146 {
147#ifdef fibGetTidPid
148 *pNativeThread = iThreadId | (fibGetPid() << 16);
149#else
150 *pNativeThread = iThreadId;
151#endif
152 return VINF_SUCCESS;
153 }
154 return RTErrConvertFromErrno(errno);
155}
156
157
158RTDECL(RTTHREAD) RTThreadSelf(void)
159{
160 PRTTHREADINT pThread = *g_ppCurThread;
161 if (pThread)
162 return (RTTHREAD)pThread;
163 /** @todo import alien threads? */
164 return NULL;
165}
166
167
168RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void)
169{
170#ifdef fibGetTidPid
171 return fibGetTidPid();
172#else
173 return _gettid();
174#endif
175}
176
177
178RTDECL(int) RTThreadSleep(unsigned cMillies)
179{
180 LogFlow(("RTThreadSleep: cMillies=%d\n", cMillies));
181 DosSleep(cMillies);
182 LogFlow(("RTThreadSleep: returning (cMillies=%d)\n", cMillies));
183 return VINF_SUCCESS;
184}
185
186
187RTDECL(bool) RTThreadYield(void)
188{
189 uint64_t u64TS = ASMReadTSC();
190 DosSleep(0);
191 u64TS = ASMReadTSC() - u64TS;
192 bool fRc = u64TS > 1750;
193 LogFlow(("RTThreadYield: returning %d (%llu ticks)\n", fRc, u64TS));
194 return fRc;
195}
196
197
198RTDECL(uint64_t) RTThreadGetAffinity(void)
199{
200 union
201 {
202 uint64_t u64;
203 MPAFFINITY mpaff;
204 } u;
205
206 int rc = DosQueryThreadAffinity(AFNTY_THREAD, &u.mpaff);
207 if (rc)
208 u.u64 = 1;
209 return u.u64;
210}
211
212
213RTDECL(int) RTThreadSetAffinity(uint64_t u64Mask)
214{
215 union
216 {
217 uint64_t u64;
218 MPAFFINITY mpaff;
219 } u;
220 u.u64 = u64Mask;
221 int rc = DosSetThreadAffinity(&u.mpaff);
222 if (!rc)
223 return VINF_SUCCESS;
224 return RTErrConvertFromOS2(rc);
225}
226
227
228RTR3DECL(RTTLS) RTTlsAlloc(void)
229{
230 AssertCompile(NIL_RTTLS == -1);
231 return __libc_TLSAlloc();
232}
233
234
235RTR3DECL(int) RTTlsAllocEx(PRTTLS piTls, PFNRTTLSDTOR pfnDestructor)
236{
237 int rc;
238 int iTls = __libc_TLSAlloc();
239 if (iTls != -1)
240 {
241 if ( !pfnDestructor
242 || __libc_TLSDestructor(iTls, (void (*)(void *, int, unsigned))pfnDestructor, 0) != -1)
243 {
244 *piTls = iTls;
245 return VINF_SUCCESS;
246 }
247
248 rc = RTErrConvertFromErrno(errno);
249 __libc_TLSFree(iTls);
250 }
251 else
252 rc = RTErrConvertFromErrno(errno);
253
254 *piTls = NIL_RTTLS;
255 return rc;
256}
257
258
259RTR3DECL(int) RTTlsFree(RTTLS iTls)
260{
261 if (iTls == NIL_RTTLS)
262 return VINF_SUCCESS;
263 if (__libc_TLSFree(iTls) != -1)
264 return VINF_SUCCESS;
265 return RTErrConvertFromErrno(errno);
266}
267
268
269RTR3DECL(void *) RTTlsGet(RTTLS iTls)
270{
271 return __libc_TLSGet(iTls);
272}
273
274
275RTR3DECL(int) RTTlsGetEx(RTTLS iTls, void **ppvValue)
276{
277 int rc = VINF_SUCCESS;
278 void *pv = __libc_TLSGet(iTls);
279 if (RT_UNLIKELY(!pv))
280 {
281 errno = 0;
282 pv = __libc_TLSGet(iTls);
283 if (!pv && errno)
284 rc = RTErrConvertFromErrno(errno);
285 }
286
287 *ppvValue = pv;
288 return rc;
289}
290
291
292RTR3DECL(int) RTTlsSet(RTTLS iTls, void *pvValue)
293{
294 if (__libc_TLSSet(iTls, pvValue) != -1)
295 return VINF_SUCCESS;
296 return RTErrConvertFromErrno(errno);
297}
298
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