trunk/src/osd/modules/lib/osdlib_macosx.cpp
| r253954 | r253955 | |
| 14 | 14 | #include <sys/types.h> |
| 15 | 15 | #include <signal.h> |
| 16 | 16 | |
| 17 | | #include <mach/mach.h> |
| 18 | | #include <mach/mach_time.h> |
| 19 | | #include <mach/mach_traps.h> |
| 20 | | #include <Carbon/Carbon.h> |
| 21 | | |
| 22 | 17 | // MAME headers |
| 23 | 18 | #include "osdcore.h" |
| 24 | 19 | #include "osdlib.h" |
| r253954 | r253955 | |
| 55 | 50 | } |
| 56 | 51 | |
| 57 | 52 | //============================================================ |
| 58 | | // osd_num_processors |
| 59 | | //============================================================ |
| 60 | | |
| 61 | | int osd_get_num_processors(void) |
| 62 | | { |
| 63 | | int processors = 1; |
| 64 | | |
| 65 | | struct host_basic_info host_basic_info; |
| 66 | | unsigned int count; |
| 67 | | kern_return_t r; |
| 68 | | mach_port_t my_mach_host_self; |
| 69 | | |
| 70 | | count = HOST_BASIC_INFO_COUNT; |
| 71 | | my_mach_host_self = mach_host_self(); |
| 72 | | if ( ( r = host_info(my_mach_host_self, HOST_BASIC_INFO, (host_info_t)(&host_basic_info), &count)) == KERN_SUCCESS ) |
| 73 | | { |
| 74 | | processors = host_basic_info.avail_cpus; |
| 75 | | } |
| 76 | | mach_port_deallocate(mach_task_self(), my_mach_host_self); |
| 77 | | |
| 78 | | return processors; |
| 79 | | } |
| 80 | | |
| 81 | | //============================================================ |
| 82 | 53 | // osd_malloc |
| 83 | 54 | //============================================================ |
| 84 | 55 | |
| r253954 | r253955 | |
| 166 | 137 | #endif |
| 167 | 138 | } |
| 168 | 139 | |
| 169 | | |
| 170 | | //============================================================ |
| 171 | | // PROTOTYPES |
| 172 | | //============================================================ |
| 173 | | |
| 174 | | static osd_ticks_t init_cycle_counter(void); |
| 175 | | static osd_ticks_t mach_cycle_counter(void); |
| 176 | | |
| 177 | | //============================================================ |
| 178 | | // STATIC VARIABLES |
| 179 | | //============================================================ |
| 180 | | |
| 181 | | static osd_ticks_t (*cycle_counter)(void) = init_cycle_counter; |
| 182 | | static osd_ticks_t (*ticks_counter)(void) = init_cycle_counter; |
| 183 | | static osd_ticks_t ticks_per_second; |
| 184 | | |
| 185 | | //============================================================ |
| 186 | | // init_cycle_counter |
| 187 | | // |
| 188 | | // to avoid total grossness, this function is split by subarch |
| 189 | | //============================================================ |
| 190 | | |
| 191 | | static osd_ticks_t init_cycle_counter(void) |
| 192 | | { |
| 193 | | osd_ticks_t start, end; |
| 194 | | osd_ticks_t a, b; |
| 195 | | |
| 196 | | cycle_counter = mach_cycle_counter; |
| 197 | | ticks_counter = mach_cycle_counter; |
| 198 | | |
| 199 | | // wait for an edge on the timeGetTime call |
| 200 | | a = SDL_GetTicks(); |
| 201 | | do |
| 202 | | { |
| 203 | | b = SDL_GetTicks(); |
| 204 | | } while (a == b); |
| 205 | | |
| 206 | | // get the starting cycle count |
| 207 | | start = (*cycle_counter)(); |
| 208 | | |
| 209 | | // now wait for 1/4 second total |
| 210 | | do |
| 211 | | { |
| 212 | | a = SDL_GetTicks(); |
| 213 | | } while (a - b < 250); |
| 214 | | |
| 215 | | // get the ending cycle count |
| 216 | | end = (*cycle_counter)(); |
| 217 | | |
| 218 | | // compute ticks_per_sec |
| 219 | | ticks_per_second = (end - start) * 4; |
| 220 | | |
| 221 | | // return the current cycle count |
| 222 | | return (*cycle_counter)(); |
| 223 | | } |
| 224 | | |
| 225 | | //============================================================ |
| 226 | | // performance_cycle_counter |
| 227 | | //============================================================ |
| 228 | | |
| 229 | | //============================================================ |
| 230 | | // mach_cycle_counter |
| 231 | | //============================================================ |
| 232 | | static osd_ticks_t mach_cycle_counter(void) |
| 233 | | { |
| 234 | | return mach_absolute_time(); |
| 235 | | } |
| 236 | | |
| 237 | | //============================================================ |
| 238 | | // osd_ticks |
| 239 | | //============================================================ |
| 240 | | |
| 241 | | osd_ticks_t osd_ticks(void) |
| 242 | | { |
| 243 | | return (*cycle_counter)(); |
| 244 | | } |
| 245 | | |
| 246 | | |
| 247 | | //============================================================ |
| 248 | | // osd_ticks_per_second |
| 249 | | //============================================================ |
| 250 | | |
| 251 | | osd_ticks_t osd_ticks_per_second(void) |
| 252 | | { |
| 253 | | if (ticks_per_second == 0) |
| 254 | | { |
| 255 | | // if we haven't computed the value yet, there's no time like the present |
| 256 | | init_cycle_counter(); |
| 257 | | } |
| 258 | | return ticks_per_second; |
| 259 | | } |
| 260 | | |
| 261 | | |
| 262 | | |
| 263 | | //============================================================ |
| 264 | | // osd_sleep |
| 265 | | //============================================================ |
| 266 | | |
| 267 | | void osd_sleep(osd_ticks_t duration) |
| 268 | | { |
| 269 | | UINT32 msec; |
| 270 | | |
| 271 | | // make sure we've computed ticks_per_second |
| 272 | | if (ticks_per_second == 0) |
| 273 | | (void)osd_ticks(); |
| 274 | | |
| 275 | | // convert to milliseconds, rounding down |
| 276 | | msec = (UINT32)(duration * 1000 / ticks_per_second); |
| 277 | | |
| 278 | | // only sleep if at least 2 full milliseconds |
| 279 | | if (msec >= 2) |
| 280 | | { |
| 281 | | // take a couple of msecs off the top for good measure |
| 282 | | msec -= 2; |
| 283 | | usleep(msec*1000); |
| 284 | | } |
| 285 | | } |
trunk/src/osd/modules/lib/osdlib_unix.cpp
| r253954 | r253955 | |
| 13 | 13 | #include <sys/mman.h> |
| 14 | 14 | #include <sys/types.h> |
| 15 | 15 | #include <signal.h> |
| 16 | | #include <time.h> |
| 17 | | #include <sys/time.h> |
| 16 | |
| 18 | 17 | #ifdef SDLMAME_EMSCRIPTEN |
| 19 | 18 | #include <emscripten.h> |
| 20 | 19 | #endif |
| r253954 | r253955 | |
| 51 | 50 | } |
| 52 | 51 | |
| 53 | 52 | //============================================================ |
| 54 | | // osd_num_processors |
| 55 | | //============================================================ |
| 56 | | |
| 57 | | int osd_get_num_processors(void) |
| 58 | | { |
| 59 | | int processors = 1; |
| 60 | | |
| 61 | | #if defined(_SC_NPROCESSORS_ONLN) |
| 62 | | processors = sysconf(_SC_NPROCESSORS_ONLN); |
| 63 | | #endif |
| 64 | | return processors; |
| 65 | | } |
| 66 | | |
| 67 | | //============================================================ |
| 68 | 53 | // osd_malloc |
| 69 | 54 | //============================================================ |
| 70 | 55 | |
| r253954 | r253955 | |
| 150 | 135 | printf("Ignoring MAME exception: %s\n", message); |
| 151 | 136 | #endif |
| 152 | 137 | } |
| 153 | | |
| 154 | | |
| 155 | | //============================================================ |
| 156 | | // osd_ticks |
| 157 | | //============================================================ |
| 158 | | |
| 159 | | osd_ticks_t osd_ticks(void) |
| 160 | | { |
| 161 | | #ifdef SDLMAME_EMSCRIPTEN |
| 162 | | return (osd_ticks_t)(emscripten_get_now() * 1000.0); |
| 163 | | #else |
| 164 | | struct timeval tp; |
| 165 | | static osd_ticks_t start_sec = 0; |
| 166 | | |
| 167 | | gettimeofday(&tp, NULL); |
| 168 | | if (start_sec==0) |
| 169 | | start_sec = tp.tv_sec; |
| 170 | | return (tp.tv_sec - start_sec) * (osd_ticks_t) 1000000 + tp.tv_usec; |
| 171 | | #endif |
| 172 | | } |
| 173 | | |
| 174 | | |
| 175 | | //============================================================ |
| 176 | | // osd_ticks_per_second |
| 177 | | //============================================================ |
| 178 | | |
| 179 | | osd_ticks_t osd_ticks_per_second(void) |
| 180 | | { |
| 181 | | return (osd_ticks_t) 1000000; |
| 182 | | } |
| 183 | | |
| 184 | | //============================================================ |
| 185 | | // osd_sleep |
| 186 | | //============================================================ |
| 187 | | |
| 188 | | void osd_sleep(osd_ticks_t duration) |
| 189 | | { |
| 190 | | UINT32 msec; |
| 191 | | |
| 192 | | // convert to milliseconds, rounding down |
| 193 | | msec = (UINT32)(duration * 1000 / osd_ticks_per_second()); |
| 194 | | |
| 195 | | // only sleep if at least 2 full milliseconds |
| 196 | | if (msec >= 2) |
| 197 | | { |
| 198 | | // take a couple of msecs off the top for good measure |
| 199 | | msec -= 2; |
| 200 | | usleep(msec*1000); |
| 201 | | } |
| 202 | | } |
trunk/src/osd/modules/lib/osdlib_win32.cpp
| r253954 | r253955 | |
| 101 | 101 | } |
| 102 | 102 | |
| 103 | 103 | //============================================================ |
| 104 | | // osd_num_processors |
| 105 | | //============================================================ |
| 106 | | |
| 107 | | int osd_get_num_processors(void) |
| 108 | | { |
| 109 | | SYSTEM_INFO info; |
| 110 | | |
| 111 | | // otherwise, fetch the info from the system |
| 112 | | GetSystemInfo(&info); |
| 113 | | |
| 114 | | // max out at 4 for now since scaling above that seems to do poorly |
| 115 | | return MIN(info.dwNumberOfProcessors, 4); |
| 116 | | } |
| 117 | | |
| 118 | | //============================================================ |
| 119 | 104 | // osd_malloc |
| 120 | 105 | //============================================================ |
| 121 | 106 | |
| r253954 | r253955 | |
| 256 | 241 | #endif |
| 257 | 242 | } |
| 258 | 243 | |
| 259 | | //============================================================ |
| 260 | | // GLOBAL VARIABLES |
| 261 | | //============================================================ |
| 262 | | |
| 263 | | static osd_ticks_t ticks_per_second = 0; |
| 264 | | static osd_ticks_t suspend_ticks = 0; |
| 265 | | static BOOL using_qpc = TRUE; |
| 266 | | |
| 267 | | |
| 268 | | |
| 269 | | //============================================================ |
| 270 | | // osd_ticks |
| 271 | | //============================================================ |
| 272 | | |
| 273 | | osd_ticks_t osd_ticks(void) |
| 274 | | { |
| 275 | | LARGE_INTEGER performance_count; |
| 276 | | |
| 277 | | // if we're suspended, just return that |
| 278 | | if (suspend_ticks != 0) |
| 279 | | return suspend_ticks; |
| 280 | | |
| 281 | | // if we have a per second count, just go for it |
| 282 | | if (ticks_per_second != 0) |
| 283 | | { |
| 284 | | // QueryPerformanceCounter if we can |
| 285 | | if (using_qpc) |
| 286 | | { |
| 287 | | QueryPerformanceCounter(&performance_count); |
| 288 | | return (osd_ticks_t)performance_count.QuadPart - suspend_ticks; |
| 289 | | } |
| 290 | | |
| 291 | | // otherwise, fall back to timeGetTime |
| 292 | | else |
| 293 | | return (osd_ticks_t)timeGetTime() - suspend_ticks; |
| 294 | | } |
| 295 | | |
| 296 | | // if not, we have to determine it |
| 297 | | using_qpc = QueryPerformanceFrequency(&performance_count) && (performance_count.QuadPart != 0); |
| 298 | | if (using_qpc) |
| 299 | | ticks_per_second = (osd_ticks_t)performance_count.QuadPart; |
| 300 | | else |
| 301 | | ticks_per_second = 1000; |
| 302 | | |
| 303 | | // call ourselves to get the first value |
| 304 | | return osd_ticks(); |
| 305 | | } |
| 306 | | |
| 307 | | |
| 308 | | //============================================================ |
| 309 | | // osd_ticks_per_second |
| 310 | | //============================================================ |
| 311 | | |
| 312 | | osd_ticks_t osd_ticks_per_second(void) |
| 313 | | { |
| 314 | | if (ticks_per_second == 0) |
| 315 | | osd_ticks(); |
| 316 | | return ticks_per_second; |
| 317 | | } |
| 318 | | |
| 319 | | //============================================================ |
| 320 | | // osd_sleep |
| 321 | | //============================================================ |
| 322 | | |
| 323 | | void osd_sleep(osd_ticks_t duration) |
| 324 | | { |
| 325 | | DWORD msec; |
| 326 | | |
| 327 | | // make sure we've computed ticks_per_second |
| 328 | | if (ticks_per_second == 0) |
| 329 | | (void)osd_ticks(); |
| 330 | | |
| 331 | | // convert to milliseconds, rounding down |
| 332 | | msec = (DWORD)(duration * 1000 / ticks_per_second); |
| 333 | | |
| 334 | | // only sleep if at least 2 full milliseconds |
| 335 | | if (msec >= 2) |
| 336 | | { |
| 337 | | HANDLE current_thread = GetCurrentThread(); |
| 338 | | int old_priority = GetThreadPriority(current_thread); |
| 339 | | |
| 340 | | // take a couple of msecs off the top for good measure |
| 341 | | msec -= 2; |
| 342 | | |
| 343 | | // bump our thread priority super high so that we get |
| 344 | | // priority when we need it |
| 345 | | SetThreadPriority(current_thread, THREAD_PRIORITY_TIME_CRITICAL); |
| 346 | | Sleep(msec); |
| 347 | | SetThreadPriority(current_thread, old_priority); |
| 348 | | } |
| 349 | | } |
trunk/src/osd/osdcore.cpp
| r253954 | r253955 | |
| 2 | 2 | // copyright-holders:Aaron Giles |
| 3 | 3 | |
| 4 | 4 | #include "osdcore.h" |
| 5 | #include <thread> |
| 6 | #include <chrono> |
| 5 | 7 | |
| 6 | 8 | static const int MAXSTACK = 10; |
| 7 | 9 | static osd_output *m_stack[MAXSTACK]; |
| r253954 | r253955 | |
| 141 | 143 | va_end(argptr); |
| 142 | 144 | } |
| 143 | 145 | #endif |
| 146 | |
| 147 | //============================================================ |
| 148 | // osd_ticks |
| 149 | //============================================================ |
| 150 | |
| 151 | osd_ticks_t osd_ticks(void) |
| 152 | { |
| 153 | return std::chrono::high_resolution_clock::now().time_since_epoch().count(); |
| 154 | } |
| 155 | |
| 156 | |
| 157 | //============================================================ |
| 158 | // osd_ticks_per_second |
| 159 | //============================================================ |
| 160 | |
| 161 | osd_ticks_t osd_ticks_per_second(void) |
| 162 | { |
| 163 | return std::chrono::high_resolution_clock::period::den; |
| 164 | } |
| 165 | |
| 166 | //============================================================ |
| 167 | // osd_sleep |
| 168 | //============================================================ |
| 169 | |
| 170 | void osd_sleep(osd_ticks_t duration) |
| 171 | { |
| 172 | std::this_thread::sleep_for(std::chrono::high_resolution_clock::duration(duration)); |
| 173 | } |
| 174 | |
| 175 | //============================================================ |
| 176 | // osd_num_processors |
| 177 | //============================================================ |
| 178 | |
| 179 | int osd_get_num_processors(void) |
| 180 | { |
| 181 | // max out at 4 for now since scaling above that seems to do poorly |
| 182 | return MIN(std::thread::hardware_concurrency(), 4); |
| 183 | } |