VirtualBox

source: vbox/trunk/src/VBox/Runtime/r0drv/solaris/timer-r0drv-solaris.c@ 8921

Last change on this file since 8921 was 8245, checked in by vboxsync, 17 years ago

rebranding: IPRT files again.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.9 KB
Line 
1/** $Id: timer-r0drv-solaris.c 8245 2008-04-21 17:24:28Z vboxsync $ */
2/** @file
3 * IPRT - Timer, Ring-0 Driver, Solaris.
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#include "the-solaris-kernel.h"
36
37#include <iprt/timer.h>
38#include <iprt/time.h>
39#include <iprt/spinlock.h>
40#include <iprt/err.h>
41#include <iprt/asm.h>
42#include <iprt/assert.h>
43#include <iprt/alloc.h>
44
45#include "internal/magics.h"
46
47
48/*******************************************************************************
49* Structures and Typedefs *
50*******************************************************************************/
51/**
52 * The internal representation of a Solaris timer handle.
53 */
54typedef struct RTTIMER
55{
56 /** Magic.
57 * This is RTTIMER_MAGIC, but changes to something else before the timer
58 * is destroyed to indicate clearly that thread should exit. */
59 uint32_t volatile u32Magic;
60 /** Flag indicating the the timer is suspended. */
61 uint8_t volatile fSuspended;
62 /** Whether the timer must run on a specific CPU or not. */
63 uint8_t fSpecificCpu;
64 /** The CPU it must run on if fSpecificCpu is set. */
65 uint8_t iCpu;
66 /** The Solaris cyclic structure. */
67 cyc_handler_t CyclicInfo;
68 /** The Solaris cyclic handle. */
69 cyclic_id_t CyclicID;
70 /** Callback. */
71 PFNRTTIMER pfnTimer;
72 /** User argument. */
73 void *pvUser;
74 /** The timer interval. 0 for one-shot timer */
75 uint64_t u64NanoInterval;
76} RTTIMER;
77
78
79/*******************************************************************************
80* Internal Functions *
81*******************************************************************************/
82static void rtTimerSolarisCallback(void *pvTimer);
83static void rtTimerSolarisStop(PRTTIMER pTimer);
84
85
86RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, unsigned fFlags, PFNRTTIMER pfnTimer, void *pvUser)
87{
88 *ppTimer = NULL;
89
90 /*
91 * Validate flags.
92 */
93 if (!RTTIMER_FLAGS_IS_VALID(fFlags))
94 return VERR_INVALID_PARAMETER;
95 if ( (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC)
96 /** @todo implement && (fFlags & RTTIMER_FLAGS_CPU_ALL) != RTTIMER_FLAGS_CPU_ALL*/)
97 return VERR_NOT_SUPPORTED;
98
99 /*
100 * Allocate and initialize the timer handle.
101 */
102 PRTTIMER pTimer = (PRTTIMER)RTMemAlloc(sizeof(*pTimer));
103 if (!pTimer)
104 return VERR_NO_MEMORY;
105
106 pTimer->u32Magic = RTTIMER_MAGIC;
107 pTimer->fSuspended = true;
108 pTimer->fSpecificCpu = !!(fFlags & RTTIMER_FLAGS_CPU_SPECIFIC);
109 pTimer->iCpu = fFlags & RTTIMER_FLAGS_CPU_MASK;
110 pTimer->CyclicInfo.cyh_func = rtTimerSolarisCallback;
111 pTimer->CyclicInfo.cyh_level = CY_LOCK_LEVEL;
112 pTimer->CyclicInfo.cyh_arg = pTimer;
113 pTimer->CyclicID = CYCLIC_NONE;
114 pTimer->u64NanoInterval = u64NanoInterval;
115 pTimer->pfnTimer = pfnTimer;
116 pTimer->pvUser = pvUser;
117
118 *ppTimer = pTimer;
119 return VINF_SUCCESS;
120}
121
122
123/**
124 * Validates the timer handle.
125 *
126 * @returns true if valid, false if invalid.
127 * @param pTimer The handle.
128 */
129DECLINLINE(bool) rtTimerIsValid(PRTTIMER pTimer)
130{
131 AssertReturn(VALID_PTR(pTimer), false);
132 AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, false);
133 return true;
134}
135
136
137RTDECL(int) RTTimerDestroy(PRTTIMER pTimer)
138{
139 if (pTimer == NULL)
140 return VINF_SUCCESS;
141 if (!rtTimerIsValid(pTimer))
142 return VERR_INVALID_HANDLE;
143
144 /*
145 * Free the associated resources.
146 */
147 pTimer->u32Magic++;
148 rtTimerSolarisStop(pTimer);
149 RTMemFree(pTimer);
150 return VINF_SUCCESS;
151}
152
153
154RTDECL(int) RTTimerStart(PRTTIMER pTimer, uint64_t u64First)
155{
156 cyc_time_t timerSpec;
157
158 if (!rtTimerIsValid(pTimer))
159 return VERR_INVALID_HANDLE;
160 if (!pTimer->fSuspended)
161 return VERR_TIMER_ACTIVE;
162
163 /*
164 * Calc when it should start fireing.
165 */
166 u64First += RTTimeNanoTS();
167
168 pTimer->fSuspended = false;
169 timerSpec.cyt_when = u64First;
170 timerSpec.cyt_interval = pTimer->u64NanoInterval == 0 ? u64First : pTimer->u64NanoInterval;
171
172 mutex_enter(&cpu_lock);
173 pTimer->CyclicID = cyclic_add(&pTimer->CyclicInfo, &timerSpec);
174 mutex_exit(&cpu_lock);
175
176 return VINF_SUCCESS;
177}
178
179
180RTDECL(int) RTTimerStop(PRTTIMER pTimer)
181{
182 if (!rtTimerIsValid(pTimer))
183 return VERR_INVALID_HANDLE;
184 if (pTimer->fSuspended)
185 return VERR_TIMER_SUSPENDED;
186
187 /*
188 * Suspend the timer.
189 */
190 pTimer->fSuspended = true;
191 rtTimerSolarisStop(pTimer);
192
193 return VINF_SUCCESS;
194}
195
196
197static void rtTimerSolarisCallback(void *pvTimer)
198{
199 PRTTIMER pTimer = (PRTTIMER)pvTimer;
200
201 /* If this is a one shot timer, call pfnTimer and suspend
202 * as Solaris does not support 0 interval timers implictly
203 */
204 if (!pTimer->u64NanoInterval)
205 {
206 pTimer->fSuspended = true;
207 rtTimerSolarisStop(pTimer);
208 }
209
210 /* Callback user defined callback function */
211 pTimer->pfnTimer(pTimer, pTimer->pvUser);
212}
213
214
215static void rtTimerSolarisStop(PRTTIMER pTimer)
216{
217 /* Important we check for invalid cyclic object */
218 if (pTimer->CyclicID != CYCLIC_NONE)
219 {
220 mutex_enter(&cpu_lock);
221 cyclic_remove(pTimer->CyclicID);
222 mutex_exit(&cpu_lock);
223 pTimer->CyclicID = CYCLIC_NONE;
224 }
225}
226
227
228RTDECL(uint32_t) RTTimerGetSystemGranularity(void)
229{
230 return nsec_per_tick;
231}
232
233
234RTDECL(int) RTTimerRequestSystemGranularity(uint32_t u32Request, uint32_t *pu32Granted)
235{
236 return VERR_NOT_SUPPORTED;
237}
238
239
240RTDECL(int) RTTimerReleaseSystemGranularity(uint32_t u32Granted)
241{
242 return VERR_NOT_SUPPORTED;
243}
244
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