VirtualBox

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

Last change on this file since 39443 was 39443, checked in by vboxsync, 13 years ago

Introduced RTThreadSleepNoLog for spinlocking in the electric fence heap. (Caused trouble with all logging enabled.)

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