1
//============================================================
3
// sdlos_*.c - OS specific low level code
5
// Copyright (c) 1996-2009, Nicola Salmoria and the MAME Team.
6
// Visit http://mamedev.org for licensing and usage restrictions.
8
// SDLMAME by Olivier Galibert and R. Belmont
10
//============================================================
12
// standard sdl header
18
#define WIN32_LEAN_AND_MEAN
24
//============================================================
26
//============================================================
28
static osd_ticks_t init_cycle_counter(void);
29
static osd_ticks_t performance_cycle_counter(void);
31
//============================================================
33
//============================================================
35
// global cycle_counter function and divider
36
static osd_ticks_t (*cycle_counter)(void) = init_cycle_counter;
37
static osd_ticks_t (*ticks_counter)(void) = init_cycle_counter;
38
static osd_ticks_t ticks_per_second;
40
//============================================================
43
// to avoid total grossness, this function is split by subarch
44
//============================================================
46
static osd_ticks_t init_cycle_counter(void)
48
osd_ticks_t start, end;
50
int priority = GetThreadPriority(GetCurrentThread());
51
LARGE_INTEGER frequency;
53
if (QueryPerformanceFrequency( &frequency ))
55
// use performance counter if available as it is constant
56
cycle_counter = performance_cycle_counter;
57
ticks_counter = performance_cycle_counter;
59
ticks_per_second = frequency.QuadPart;
61
// return the current cycle count
62
return (*cycle_counter)();
66
fprintf(stderr, "Error! Unable to QueryPerformanceFrequency!\n");
70
// temporarily set our priority higher
71
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
73
// wait for an edge on the timeGetTime call
80
// get the starting cycle count
81
start = (*cycle_counter)();
83
// now wait for 1/4 second total
87
} while (a - b < 250);
89
// get the ending cycle count
90
end = (*cycle_counter)();
92
// compute ticks_per_sec
93
ticks_per_second = (end - start) * 4;
95
// restore our priority
96
SetThreadPriority(GetCurrentThread(), priority);
98
// return the current cycle count
99
return (*cycle_counter)();
102
//============================================================
103
// performance_cycle_counter
104
//============================================================
106
static osd_ticks_t performance_cycle_counter(void)
108
LARGE_INTEGER performance_count;
109
QueryPerformanceCounter(&performance_count);
110
return (osd_ticks_t)performance_count.QuadPart;
113
//============================================================
115
//============================================================
117
osd_ticks_t osd_ticks(void)
119
return (*cycle_counter)();
123
//============================================================
124
// osd_ticks_per_second
125
//============================================================
127
osd_ticks_t osd_ticks_per_second(void)
129
if (ticks_per_second == 0)
131
return 1; // this isn't correct, but it prevents the crash
133
return ticks_per_second;
136
//============================================================
138
//============================================================
140
void osd_sleep(osd_ticks_t duration)
144
// make sure we've computed ticks_per_second
145
if (ticks_per_second == 0)
148
// convert to milliseconds, rounding down
149
msec = (UINT32)(duration * 1000 / ticks_per_second);
151
// only sleep if at least 2 full milliseconds
154
// take a couple of msecs off the top for good measure
160
//============================================================
161
// osd_num_processors
162
//============================================================
164
int osd_num_processors(void)
168
// otherwise, fetch the info from the system
169
GetSystemInfo(&info);
171
// max out at 4 for now since scaling above that seems to do poorly
172
return MIN(info.dwNumberOfProcessors, 4);
175
//============================================================
176
// osd_alloc_executable
178
// allocates "size" bytes of executable memory. this must take
179
// things like NX support into account.
180
//============================================================
182
void *osd_alloc_executable(size_t size)
184
return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
187
//============================================================
188
// osd_free_executable
190
// frees memory allocated with osd_alloc_executable
191
//============================================================
193
void osd_free_executable(void *ptr, size_t size)
195
VirtualFree(ptr, 0, MEM_RELEASE);
198
//============================================================
199
// osd_break_into_debugger
200
//============================================================
202
void osd_break_into_debugger(const char *message)
204
if (IsDebuggerPresent())
206
OutputDebugString(message);