~ubuntu-branches/ubuntu/gutsy/virtualbox-ose/gutsy

« back to all changes in this revision

Viewing changes to src/VBox/Runtime/r3/os2/thread-os2.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2007-09-08 16:44:58 UTC
  • Revision ID: james.westby@ubuntu.com-20070908164458-wao29470vqtr8ksy
Tags: upstream-1.5.0-dfsg2
ImportĀ upstreamĀ versionĀ 1.5.0-dfsg2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: thread-os2.cpp 4071 2007-08-07 17:07:59Z vboxsync $ */
 
2
/** @file
 
3
 * innotek Portable Runtime - Threads, OS/2.
 
4
 */
 
5
 
 
6
/*
 
7
 * Copyright (C) 2006-2007 innotek GmbH
 
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 as published by the Free Software Foundation,
 
13
 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
 
14
 * distribution. VirtualBox OSE is distributed in the hope that it will
 
15
 * be useful, but WITHOUT ANY WARRANTY of any kind.
 
16
 */
 
17
 
 
18
 
 
19
/*******************************************************************************
 
20
*   Header Files                                                               *
 
21
*******************************************************************************/
 
22
#define LOG_GROUP RTLOGGROUP_THREAD
 
23
#define INCL_BASE
 
24
#include <os2.h>
 
25
#undef RT_MAX
 
26
 
 
27
#include <errno.h>
 
28
#include <process.h>
 
29
#include <stdlib.h>
 
30
#include <signal.h>
 
31
#include <InnoTekLIBC/FastInfoBlocks.h>
 
32
 
 
33
#include <iprt/thread.h>
 
34
#include <iprt/log.h>
 
35
#include <iprt/assert.h>
 
36
#include <iprt/alloc.h>
 
37
#include <iprt/asm.h>
 
38
#include <iprt/string.h>
 
39
#include <iprt/err.h>
 
40
#include "internal/thread.h"
 
41
 
 
42
 
 
43
/*******************************************************************************
 
44
*   Global Variables                                                           *
 
45
*******************************************************************************/
 
46
/** Pointer to thread local memory which points to the current thread. */
 
47
static PRTTHREADINT *g_ppCurThread;
 
48
 
 
49
 
 
50
/*******************************************************************************
 
51
*   Internal Functions                                                         *
 
52
*******************************************************************************/
 
53
static void rtThreadNativeMain(void *pvArgs);
 
54
 
 
55
 
 
56
int rtThreadNativeInit(void)
 
57
{
 
58
    /*
 
59
     * Allocate thread local memory.
 
60
     */
 
61
    PULONG pul;
 
62
    int rc = DosAllocThreadLocalMemory(1, &pul);
 
63
    if (rc)
 
64
        return VERR_NO_TLS_FOR_SELF;
 
65
    g_ppCurThread = (PRTTHREADINT *)(void *)pul;
 
66
    return VINF_SUCCESS;
 
67
}
 
68
 
 
69
 
 
70
int rtThreadNativeAdopt(PRTTHREADINT pThread)
 
71
{
 
72
    /*
 
73
     * Block SIGALRM - required for timer-posix.cpp.
 
74
     * This is done to limit harm done by OSes which doesn't do special SIGALRM scheduling.
 
75
     * It will not help much if someone creates threads directly using pthread_create. :/
 
76
     */
 
77
    sigset_t SigSet;
 
78
    sigemptyset(&SigSet);
 
79
    sigaddset(&SigSet, SIGALRM);
 
80
    sigprocmask(SIG_BLOCK, &SigSet, NULL);
 
81
 
 
82
    *g_ppCurThread = pThread;
 
83
    return VINF_SUCCESS;
 
84
}
 
85
 
 
86
 
 
87
/**
 
88
 * Wrapper which unpacks the params and calls thread function.
 
89
 */
 
90
static void rtThreadNativeMain(void *pvArgs)
 
91
{
 
92
    /*
 
93
     * Block SIGALRM - required for timer-posix.cpp.
 
94
     * This is done to limit harm done by OSes which doesn't do special SIGALRM scheduling.
 
95
     * It will not help much if someone creates threads directly using pthread_create. :/
 
96
     */
 
97
    sigset_t SigSet;
 
98
    sigemptyset(&SigSet);
 
99
    sigaddset(&SigSet, SIGALRM);
 
100
    sigprocmask(SIG_BLOCK, &SigSet, NULL);
 
101
 
 
102
    /*
 
103
     * Call common main.
 
104
     */
 
105
    PRTTHREADINT  pThread = (PRTTHREADINT)pvArgs;
 
106
    *g_ppCurThread = pThread;
 
107
 
 
108
#ifdef fibGetTidPid
 
109
    rtThreadMain(pThread, fibGetTidPid(), &pThread->szName[0]);
 
110
#else
 
111
    rtThreadMain(pThread, _gettid(), &pThread->szName[0]);
 
112
#endif
 
113
 
 
114
    *g_ppCurThread = NULL;
 
115
    _endthread();
 
116
}
 
117
 
 
118
 
 
119
int rtThreadNativeCreate(PRTTHREADINT pThread, PRTNATIVETHREAD pNativeThread)
 
120
{
 
121
    /*
 
122
     * Default stack size.
 
123
     */
 
124
    if (!pThread->cbStack)
 
125
        pThread->cbStack = 512*1024;
 
126
 
 
127
    /*
 
128
     * Create the thread.
 
129
     */
 
130
    int iThreadId = _beginthread(rtThreadNativeMain, NULL, pThread->cbStack, pThread);
 
131
    if (iThreadId > 0)
 
132
    {
 
133
#ifdef fibGetTidPid
 
134
        *pNativeThread = iThreadId | (fibGetPid() << 16);
 
135
#else
 
136
        *pNativeThread = iThreadId;
 
137
#endif
 
138
        return VINF_SUCCESS;
 
139
    }
 
140
    return RTErrConvertFromErrno(errno);
 
141
}
 
142
 
 
143
 
 
144
RTDECL(RTTHREAD) RTThreadSelf(void)
 
145
{
 
146
    PRTTHREADINT pThread = *g_ppCurThread;
 
147
    if (pThread)
 
148
        return (RTTHREAD)pThread;
 
149
    /** @todo import alien threads? */
 
150
    return NULL;
 
151
}
 
152
 
 
153
 
 
154
RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void)
 
155
{
 
156
#ifdef fibGetTidPid
 
157
    return fibGetTidPid();
 
158
#else
 
159
    return _gettid();
 
160
#endif
 
161
}
 
162
 
 
163
 
 
164
RTDECL(int)   RTThreadSleep(unsigned cMillies)
 
165
{
 
166
    LogFlow(("RTThreadSleep: cMillies=%d\n", cMillies));
 
167
    DosSleep(cMillies);
 
168
    LogFlow(("RTThreadSleep: returning (cMillies=%d)\n", cMillies));
 
169
    return VINF_SUCCESS;
 
170
}
 
171
 
 
172
 
 
173
RTDECL(bool) RTThreadYield(void)
 
174
{
 
175
    uint64_t u64TS = ASMReadTSC();
 
176
    DosSleep(0);
 
177
    u64TS = ASMReadTSC() - u64TS;
 
178
    bool fRc = u64TS > 1750;
 
179
    LogFlow(("RTThreadYield: returning %d (%llu ticks)\n", fRc, u64TS));
 
180
    return fRc;
 
181
}
 
182
 
 
183
 
 
184
RTDECL(uint64_t) RTThreadGetAffinity(void)
 
185
{
 
186
    union
 
187
    {
 
188
        uint64_t u64;
 
189
        MPAFFINITY mpaff;
 
190
    } u;
 
191
 
 
192
    int rc = DosQueryThreadAffinity(AFNTY_THREAD, &u.mpaff);
 
193
    if (rc)
 
194
        u.u64 = 1;
 
195
    return u.u64;
 
196
}
 
197
 
 
198
 
 
199
RTDECL(int) RTThreadSetAffinity(uint64_t u64Mask)
 
200
{
 
201
    union
 
202
    {
 
203
        uint64_t u64;
 
204
        MPAFFINITY mpaff;
 
205
    } u;
 
206
    u.u64 = u64Mask;
 
207
    int rc = DosSetThreadAffinity(&u.mpaff);
 
208
    if (!rc)
 
209
        return VINF_SUCCESS;
 
210
    return RTErrConvertFromOS2(rc);
 
211
}
 
212