VirtualBox

source: vbox/trunk/src/VBox/Runtime/r0drv/freebsd/thread-r0drv-freebsd.c@ 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 Author Date Id Revision
File size: 4.5 KB
Line 
1/* $Id: thread-r0drv-freebsd.c 39443 2011-11-28 15:01:21Z vboxsync $ */
2/** @file
3 * IPRT - Threads (Part 1), Ring-0 Driver, FreeBSD.
4 */
5
6/*
7 * Copyright (C) 2007-2009 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* Header Files *
29*******************************************************************************/
30#include "the-freebsd-kernel.h"
31#include "internal/iprt.h"
32#include <iprt/thread.h>
33
34#include <iprt/asm.h>
35#include <iprt/asm-amd64-x86.h>
36#include <iprt/assert.h>
37#include <iprt/err.h>
38#include <iprt/mp.h>
39#include "internal/thread.h"
40
41
42RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void)
43{
44 return (RTNATIVETHREAD)curthread;
45}
46
47
48static int rtR0ThreadFbsdSleepCommon(RTMSINTERVAL cMillies)
49{
50 int rc;
51 int cTicks;
52
53 /*
54 * 0 ms sleep -> yield.
55 */
56 if (!cMillies)
57 {
58 RTThreadYield();
59 return VINF_SUCCESS;
60 }
61
62 /*
63 * Translate milliseconds into ticks and go to sleep.
64 */
65 if (cMillies != RT_INDEFINITE_WAIT)
66 {
67 if (hz == 1000)
68 cTicks = cMillies;
69 else if (hz == 100)
70 cTicks = cMillies / 10;
71 else
72 {
73 int64_t cTicks64 = ((uint64_t)cMillies * hz) / 1000;
74 cTicks = (int)cTicks64;
75 if (cTicks != cTicks64)
76 cTicks = INT_MAX;
77 }
78 }
79 else
80 cTicks = 0; /* requires giant lock! */
81
82 rc = tsleep((void *)RTThreadSleep,
83 PZERO | PCATCH,
84 "iprtsl", /* max 6 chars */
85 cTicks);
86 switch (rc)
87 {
88 case 0:
89 return VINF_SUCCESS;
90 case EWOULDBLOCK:
91 return VERR_TIMEOUT;
92 case EINTR:
93 case ERESTART:
94 return VERR_INTERRUPTED;
95 default:
96 AssertMsgFailed(("%d\n", rc));
97 return VERR_NO_TRANSLATION;
98 }
99}
100
101
102RTDECL(int) RTThreadSleep(RTMSINTERVAL cMillies)
103{
104 return rtR0ThreadFbsdSleepCommon(cMillies);
105}
106
107
108RTDECL(int) RTThreadSleepNoLog(RTMSINTERVAL cMillies)
109{
110 return rtR0ThreadFbsdSleepCommon(cMillies);
111}
112
113
114RTDECL(bool) RTThreadYield(void)
115{
116#if __FreeBSD_version >= 900032
117 kern_yield(curthread->td_user_pri);
118#else
119 uio_yield();
120#endif
121 return false; /** @todo figure this one ... */
122}
123
124
125RTDECL(bool) RTThreadPreemptIsEnabled(RTTHREAD hThread)
126{
127 Assert(hThread == NIL_RTTHREAD);
128
129 return curthread->td_critnest == 0
130 && ASMIntAreEnabled(); /** @todo is there a native freebsd function/macro for this? */
131}
132
133
134RTDECL(bool) RTThreadPreemptIsPending(RTTHREAD hThread)
135{
136 Assert(hThread == NIL_RTTHREAD);
137
138 return curthread->td_owepreempt == 1;
139}
140
141
142RTDECL(bool) RTThreadPreemptIsPendingTrusty(void)
143{
144 /* yes, RTThreadPreemptIsPending is reliable. */
145 return true;
146}
147
148
149RTDECL(bool) RTThreadPreemptIsPossible(void)
150{
151 /* yes, kernel preemption is possible. */
152 return true;
153}
154
155
156RTDECL(void) RTThreadPreemptDisable(PRTTHREADPREEMPTSTATE pState)
157{
158 AssertPtr(pState);
159 Assert(pState->u32Reserved == 0);
160 pState->u32Reserved = 42;
161
162 critical_enter();
163 RT_ASSERT_PREEMPT_CPUID_DISABLE(pState);
164}
165
166
167RTDECL(void) RTThreadPreemptRestore(PRTTHREADPREEMPTSTATE pState)
168{
169 AssertPtr(pState);
170 Assert(pState->u32Reserved == 42);
171 pState->u32Reserved = 0;
172
173 RT_ASSERT_PREEMPT_CPUID_RESTORE(pState);
174 critical_exit();
175}
176
177
178RTDECL(bool) RTThreadIsInInterrupt(RTTHREAD hThread)
179{
180 Assert(hThread == NIL_RTTHREAD); NOREF(hThread);
181 /** @todo FreeBSD: Implement RTThreadIsInInterrupt. Required for guest
182 * additions! */
183 return !ASMIntAreEnabled();
184}
185
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