src/os_timer.cpp
author rubidium
Thu, 19 Jun 2008 11:45:52 +0000
changeset 11023 583f32658248
parent 10429 1b99254f9607
permissions -rw-r--r--
(svn r13579) -Fix [FS#2088]: process the order coming after a conditional order, otherwise the vehicle would already leaving the station before it knows where the next destination is, making it leave in the wrong way. However, after processing as many conditional orders as there are in the order list it will stop processing them in order to not create an infinite loop.
3383
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
     1
/* $Id$ */
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
     2
10429
1b99254f9607 (svn r12971) -Documentation: add @file in files that missed them and add something more than whitespace as description of files that don't have a description.
rubidium
parents: 7901
diff changeset
     3
/** @file os_timer.cpp OS/compiler dependant real time tick sampling. */
6677
0578c2e31ed1 (svn r9390) -Documentation : correct Doxygen of comments and @file inclusion. This time, brought to you by the letter O
belugas
parents: 6573
diff changeset
     4
3383
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
     5
#include "stdafx.h"
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
     6
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
     7
#undef RDTSC_AVAILABLE
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
     8
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
     9
/* rdtsc for MSC_VER, uses simple inline assembly, or _rdtsc
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    10
 * from external win64.asm because VS2005 does not support inline assembly */
7901
1af11255e634 (svn r10778) -Fix: one-liners to allow MSVC and WINCE to work together (or anyway, a step towards that goal)
truelight
parents: 6677
diff changeset
    11
#if defined(_MSC_VER) && !defined(RDTSC_AVAILABLE) && !defined(WINCE)
6497
b7170a1ffb33 (svn r8933) -Fix [Win64]: rdtsc now uses intrinsic on VC8 (michi_cc)
KUDr
parents: 5835
diff changeset
    12
# if _MSC_VER >= 1400
b7170a1ffb33 (svn r8933) -Fix [Win64]: rdtsc now uses intrinsic on VC8 (michi_cc)
KUDr
parents: 5835
diff changeset
    13
#include <intrin.h>
6573
7624f942237f (svn r9050) -Codechange: Foo(void) -> Foo()
rubidium
parents: 6497
diff changeset
    14
uint64 _rdtsc()
6497
b7170a1ffb33 (svn r8933) -Fix [Win64]: rdtsc now uses intrinsic on VC8 (michi_cc)
KUDr
parents: 5835
diff changeset
    15
{
b7170a1ffb33 (svn r8933) -Fix [Win64]: rdtsc now uses intrinsic on VC8 (michi_cc)
KUDr
parents: 5835
diff changeset
    16
	return __rdtsc();
b7170a1ffb33 (svn r8933) -Fix [Win64]: rdtsc now uses intrinsic on VC8 (michi_cc)
KUDr
parents: 5835
diff changeset
    17
}
3383
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    18
#	else
6573
7624f942237f (svn r9050) -Codechange: Foo(void) -> Foo()
rubidium
parents: 6497
diff changeset
    19
uint64 _declspec(naked) _rdtsc()
3383
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    20
{
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    21
	_asm {
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    22
		rdtsc
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    23
		ret
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    24
	}
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    25
}
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    26
# endif
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    27
# define RDTSC_AVAILABLE
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    28
#endif
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    29
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    30
/* rdtsc for OS/2. Hopefully this works, who knows */
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    31
#if defined (__WATCOMC__) && !defined(RDTSC_AVAILABLE)
6573
7624f942237f (svn r9050) -Codechange: Foo(void) -> Foo()
rubidium
parents: 6497
diff changeset
    32
unsigned __int64 _rdtsc();
3383
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    33
# pragma aux _rdtsc = 0x0F 0x31 value [edx eax] parm nomemory modify exact [edx eax] nomemory;
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    34
# define RDTSC_AVAILABLE
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    35
#endif
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    36
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    37
/* rdtsc for all other *nix-en (hopefully). Use GCC syntax */
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    38
#if defined(__i386__) || defined(__x86_64__) && !defined(RDTSC_AVAILABLE)
6573
7624f942237f (svn r9050) -Codechange: Foo(void) -> Foo()
rubidium
parents: 6497
diff changeset
    39
uint64 _rdtsc()
3383
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    40
{
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    41
	uint32 high, low;
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    42
	__asm__ __volatile__ ("rdtsc" : "=a" (low), "=d" (high));
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    43
	return ((uint64)high << 32) | low;
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    44
}
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    45
# define RDTSC_AVAILABLE
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    46
#endif
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    47
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    48
/* rdtsc for PPC which has this not */
5551
5cc56d0e6f5f (svn r7548) -Codechange: Some MorphOS changes to get OpenTTD compiled, packaged (tokai)
Darkvater
parents: 3407
diff changeset
    49
#if (defined(__POWERPC__) || defined(__powerpc__)) && !defined(RDTSC_AVAILABLE)
6573
7624f942237f (svn r9050) -Codechange: Foo(void) -> Foo()
rubidium
parents: 6497
diff changeset
    50
uint64 _rdtsc()
3383
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    51
{
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    52
	uint32 high = 0, high2 = 0, low;
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    53
	/* PPC does not have rdtsc, so we cheat by reading the two 32-bit time-counters
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    54
	 * it has, 'Move From Time Base (Upper)'. Since these are two reads, in the
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    55
	 * very unlikely event that the lower part overflows to the upper part while we
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    56
	 * read it; we double-check and reread the registers */
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    57
	asm volatile (
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    58
				  "mftbu %0\n"
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    59
				  "mftb %1\n"
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    60
				  "mftbu %2\n"
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    61
				  "cmpw %3,%4\n"
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    62
				  "bne- $-16\n"
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    63
				  : "=r" (high), "=r" (low), "=r" (high2)
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    64
				  : "0" (high), "2" (high2)
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    65
				  );
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    66
	return ((uint64)high << 32) | low;
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    67
}
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    68
# define RDTSC_AVAILABLE
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    69
#endif
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    70
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    71
/* In all other cases we have no support for rdtsc. No major issue,
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    72
 * you just won't be able to profile your code with TIC()/TOC() */
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    73
#if !defined(RDTSC_AVAILABLE)
7901
1af11255e634 (svn r10778) -Fix: one-liners to allow MSVC and WINCE to work together (or anyway, a step towards that goal)
truelight
parents: 6677
diff changeset
    74
/* MSVC (in case of WinCE) can't handle #warning */
1af11255e634 (svn r10778) -Fix: one-liners to allow MSVC and WINCE to work together (or anyway, a step towards that goal)
truelight
parents: 6677
diff changeset
    75
# if !defined(_MSC_VER)
3407
eb0845aa1db7 (svn r4218) - Codechange: Try to make the rdtsc() not present warning message a bit more clear
Darkvater
parents: 3383
diff changeset
    76
#warning "(non-fatal) No support for rdtsc(), you won't be able to profile with TIC/TOC"
7901
1af11255e634 (svn r10778) -Fix: one-liners to allow MSVC and WINCE to work together (or anyway, a step towards that goal)
truelight
parents: 6677
diff changeset
    77
# endif
6573
7624f942237f (svn r9050) -Codechange: Foo(void) -> Foo()
rubidium
parents: 6497
diff changeset
    78
uint64 _rdtsc() {return 0;}
3383
24871cb73dbf (svn r4191) - Codechange: Properly set newlines and id for os_timer.c
Darkvater
parents: 3362
diff changeset
    79
#endif