diff options
author | David Schleef <ds@schleef.org> | 2006-04-21 15:40:31 +0000 |
---|---|---|
committer | David Schleef <ds@schleef.org> | 2006-04-21 15:40:31 +0000 |
commit | 1f08019b6ecc19f6e1096c4a3910bdcd58029a4e (patch) | |
tree | 615e782e759b808438b65a0eeec21d3456d90361 | |
parent | 3d5eeee9d9788e83663c7472cd0b50a79ce667d5 (diff) | |
download | liboil-1f08019b6ecc19f6e1096c4a3910bdcd58029a4e.tar.gz |
* Makefile.am:
* liboil/Makefile.am: dist various files
* liboil/liboildebug.c: debug fix
* liboil/liboilfunction.c: doc fix
* liboil/liboilcpu.c: move timestamp code here, since it depends
closely on the cpu detection code.
* liboil/liboilprofile.c:
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | liboil/Makefile.am | 4 | ||||
-rw-r--r-- | liboil/liboilcpu.c | 619 | ||||
-rw-r--r-- | liboil/liboildebug.c | 2 | ||||
-rw-r--r-- | liboil/liboilfunction.c | 19 | ||||
-rw-r--r-- | liboil/liboilprofile.c | 166 |
7 files changed, 440 insertions, 382 deletions
@@ -1,3 +1,13 @@ +2006-04-21 David Schleef <ds@schleef.org> + + * Makefile.am: + * liboil/Makefile.am: dist various files + * liboil/liboildebug.c: debug fix + * liboil/liboilfunction.c: doc fix + * liboil/liboilcpu.c: move timestamp code here, since it depends + closely on the cpu detection code. + * liboil/liboilprofile.c: + 2006-03-21 David Schleef <ds@schleef.org> * configure.ac: version 0.3.8 diff --git a/Makefile.am b/Makefile.am index 57e5932..278ef14 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,7 +3,7 @@ AUTOMAKE_OPTIONS = foreign SUBDIRS = liboil testsuite examples doc -EXTRA_DIST = COPYING autogen.sh gtk-doc.make +EXTRA_DIST = COPYING autogen.sh gtk-doc.make HACKING pkgconfig_DATA = liboil-$(LIBOIL_MAJORMINOR).pc diff --git a/liboil/Makefile.am b/liboil/Makefile.am index 62f21b1..c775c48 100644 --- a/liboil/Makefile.am +++ b/liboil/Makefile.am @@ -4,6 +4,8 @@ pkgincludedir = $(includedir)/liboil-@LIBOIL_MAJORMINOR@/liboil DIST_SUBDIRS = amd64 3dnow c colorspace conv copy dct fb i386 jpeg math md5 mmx motovec powerpc powerpc_asm_blocks ref simdpack sse utf8 deprecated SUBDIRS = c colorspace conv copy dct jpeg math md5 ref simdpack utf8 deprecated +EXTRA_DIST = README + libs = if HAVE_I386 @@ -204,7 +206,7 @@ liboilmarshal.c: liboilfuncs-doc.h: ./build_prototypes_doc$(EXEEXT) >liboilfuncs-doc.h -update: build_prototypes$(EXEEXT) build_marshal$(EXEEXT) build_prototypes_doc$(EXEEXT) build_class_decls$(EXEEXT) +update: build_prototypes$(EXEEXT) build_marshal$(EXEEXT) build_prototypes_doc$(EXEEXT) build_class_decls$(EXEEXT) build_trampolines$(EXTEXT) build_prototypes_04$(EXTEXT) ./build_prototypes$(EXEEXT) >liboilfuncs.h ./build_marshal$(EXEEXT) >liboilmarshal.c ./build_prototypes_doc$(EXEEXT) >liboilfuncs-doc.h diff --git a/liboil/liboilcpu.c b/liboil/liboilcpu.c index 9f01941..abdc7d7 100644 --- a/liboil/liboilcpu.c +++ b/liboil/liboilcpu.c @@ -39,6 +39,8 @@ #include <stdio.h> #include <setjmp.h> #include <signal.h> +#include <sys/time.h> +#include <time.h> #if defined(__FreeBSD__) #include <sys/types.h> @@ -52,16 +54,207 @@ * */ -#if defined(__linux__) && (defined(__i386__) || defined(__amd64__)) -static char * get_cpuinfo_flags_string (char *cpuinfo); -static char ** strsplit (char *s); -static char * _strndup (const char *s, int n); -#endif +static void oil_cpu_detect_arch(void); static unsigned long oil_cpu_flags; -#if defined(__linux__) && (defined(__i386__) || defined(__amd64__)) -static char * +extern unsigned long (*_oil_profile_stamp)(void); + +#if defined(__linux__) && defined(__arm__) +#define USE_CPUINFO +#endif + + +#ifdef HAVE_GETTIMEOFDAY +static unsigned long +oil_profile_stamp_gtod (void) +{ + struct timeval tv; + gettimeofday(&tv,NULL); + return 1000000*(unsigned long)tv.tv_sec + (unsigned long)tv.tv_usec; +} +#endif + +static unsigned long +oil_profile_stamp_zero (void) +{ + return 0; +} + +void +_oil_cpu_init (void) +{ + const char *envvar; + + oil_cpu_detect_arch(); + + envvar = getenv ("OIL_CPU_FLAGS"); + if (envvar != NULL) { + char *end = NULL; + unsigned long flags; + + flags = strtoul (envvar, &end, 0); + if (end > envvar) { + oil_cpu_flags = flags; + } + OIL_INFO ("cpu flags from environment %08lx", oil_cpu_flags); + } + + OIL_INFO ("cpu flags %08lx", oil_cpu_flags); + +#ifdef HAVE_GETTIMEOFDAY + if (_oil_profile_stamp == NULL) { + _oil_profile_stamp = oil_profile_stamp_gtod; + OIL_WARNING("Using gettimeofday() as a timestamp function."); + } +#endif + if (_oil_profile_stamp == NULL) { + _oil_profile_stamp = oil_profile_stamp_zero; + OIL_ERROR("No timestamping function. This is kinda bad."); + } +} + +/** + * oil_cpu_get_flags: + * + * Returns a bitmask containing the available CPU features. + * + * Returns: the CPU features. + */ +unsigned int +oil_cpu_get_flags (void) +{ + return oil_cpu_flags; +} + + +static jmp_buf jump_env; +#ifdef HAVE_SIGACTION +static struct sigaction action; +static struct sigaction oldaction; +#else +static void * oldhandler; +#endif +static int in_try_block; +static int enable_level; + +static void +illegal_instruction_handler (int num) +{ + if (in_try_block) { + longjmp (jump_env, 1); + } else { + abort (); + } +} + +/** + * oil_cpu_fault_check_enable: + * + * Enables fault checking mode. This function may be called multiple times. + * Each call to this function must be paired with a corresponding call + * to oil_cpu_fault_check_disable(). + * + * This function sets a signal handler for SIGILL. + */ +void +oil_cpu_fault_check_enable (void) +{ + if (enable_level == 0) { +#ifdef HAVE_SIGACTION + memset (&action, 0, sizeof(action)); + action.sa_handler = &illegal_instruction_handler; + sigaction (SIGILL, &action, &oldaction); +#else + oldhandler = signal (SIGILL, illegal_instruction_handler); +#endif + in_try_block = 0; + OIL_INFO("enabling SIGILL handler. Make sure to continue past " + "any SIGILL signals caught by gdb."); + } + enable_level++; +} + +/** + * oil_cpu_fault_check_try: + * @func: the function to attempt + * @priv: a value to pass to the function + * + * Calls to this + * function must be preceded by a call to oil_cpu_fault_check_enable() + * to enable fault checking mode. This function sets up recovery + * information and then calls the function @func with the parameter + * @priv. If @func or any other functions it calls attempt to execute + * an illegal instruction, the exception will be caught and recovered from. + * + * Returns: 1 if the function was executed sucessfully, 0 if the + * function attempted to execute an illegal instruction. + */ +int +oil_cpu_fault_check_try (void (*func) (void *), void *priv) +{ + int ret; + + in_try_block = 1; + ret = setjmp (jump_env); + if (!ret) { + func (priv); + } + in_try_block = 0; + + return (ret == 0); +} + +/** + * oil_cpu_fault_check_disable: + * + * Disables fault checking mode. See oil_cpu_fault_check_enable() + * for details. + */ +void +oil_cpu_fault_check_disable (void) +{ + enable_level--; + if (enable_level == 0) { +#ifdef HAVE_SIGACTION + sigaction (SIGILL, &oldaction, NULL); +#else + signal (SIGILL, oldhandler); +#endif + OIL_INFO("disabling SIGILL handler"); + } +} + +#if 0 +/** + * oil_cpu_get_ticks_per_second: + * + * Returns the estimated number of ticks per second. This feature + * is currently unimplemented. + * + * This function may take several milliseconds or more to execute + * in order to calculate a good estimate of the number of ticks (as + * measured by the profiling functions) per second. Note that the + * number of ticks per second is often dependent on the CPU frequency, + * which can change dynamically. Thus the value returned by this + * function may be incorrect as soon as it is returned. + * + * Returns: a double + */ +double +oil_cpu_get_ticks_per_second (void) +{ + return _oil_ticks_per_second; +} +#endif + + +#ifdef USE_CPUINFO +static char * get_cpuinfo_line (char *cpuinfo, const char *tag); +static char ** strsplit (char *s); +static char * _strndup (const char *s, int n); + +char * get_proc_cpuinfo (void) { char *cpuinfo; @@ -90,6 +283,70 @@ get_proc_cpuinfo (void) return cpuinfo; } +static char * +get_cpuinfo_line (char *cpuinfo, const char *tag) +{ + char *flags; + char *end; + char *colon; + + flags = strstr(cpuinfo,tag); + if (flags == NULL) return NULL; + + end = strchr(flags, '\n'); + if (end == NULL) return NULL; + colon = strchr (flags, ':'); + if (colon == NULL) return NULL; + colon++; + if(colon >= end) return NULL; + + return _strndup (colon, end-colon); +} + +static char ** +strsplit (char *s) +{ + char **list = NULL; + char *tok; + int n = 0; + + while (*s == ' ') s++; + + list = malloc (1 * sizeof(char *)); + while (*s) { + tok = s; + while (*s && *s != ' ') s++; + + list[n] = _strndup (tok, s - tok); + while (*s && *s == ' ') s++; + list = realloc (list, (n + 2) * sizeof(char *)); + n++; + } + + list[n] = NULL; + return list; +} + +static char * +_strndup (const char *s, int n) +{ + char *r; + r = malloc (n+1); + memcpy(r,s,n); + r[n]=0; + + return r; +} +#endif + + + +/***** i386, amd64 *****/ + +#if defined(__i386__) || defined(__amd64__) + +#if 0 +#if defined(__linux__) static void oil_cpu_i386_getflags_cpuinfo (char *cpuinfo) { @@ -97,7 +354,7 @@ oil_cpu_i386_getflags_cpuinfo (char *cpuinfo) char **flags; char **f; - cpuinfo_flags = get_cpuinfo_flags_string(cpuinfo); + cpuinfo_flags = get_cpuinfo_tag(cpuinfo, "flags"); if (cpuinfo_flags == NULL) { free (cpuinfo); return; @@ -142,8 +399,15 @@ oil_cpu_i386_getflags_cpuinfo (char *cpuinfo) free (cpuinfo_flags); } #endif +#endif -#if defined(__i386__) || defined(__amd64__) +static unsigned long +oil_profile_stamp_rdtsc(void) +{ + unsigned long ts; + __asm__ __volatile__("rdtsc\n" : "=a" (ts) : : "edx"); + return ts; +} #ifdef __i386__ static void @@ -181,8 +445,8 @@ test_cpuid (void *ignored) get_cpuid (0x00000000, &eax, &ebx, &ecx, &edx); } -static void -oil_cpu_i386_getflags_cpuid (void) +static int +oil_cpu_detect_cpuid (void) { uint32_t eax, ebx, ecx, edx; uint32_t level; @@ -194,7 +458,7 @@ oil_cpu_i386_getflags_cpuid (void) oil_cpu_fault_check_disable (); if (!ret) { /* CPU thinks cpuid is an illegal instruction. */ - return; + return 0; } get_cpuid (0x00000000, &level, (uint32_t *)(vendor+0), @@ -203,11 +467,15 @@ oil_cpu_i386_getflags_cpuid (void) OIL_DEBUG("cpuid %d %s", level, vendor); if (level < 1) { - return; + return 0; } get_cpuid (0x00000001, &eax, &ebx, &ecx, &edx); + if (edx & (1<<4)) { + _oil_profile_stamp = oil_profile_stamp_rdtsc; + } + /* Intel flags */ if (edx & (1<<15)) { oil_cpu_flags |= OIL_IMPL_FLAG_CMOV; @@ -262,7 +530,7 @@ oil_cpu_i386_getflags_cpuid (void) * SSE, then it's safe. */ static void -oil_cpu_i386_kernel_restrict_flags(void) +oil_cpu_detect_kernel_support (void) { #ifdef __FreeBSD__ int ret, enabled; @@ -288,9 +556,9 @@ oil_cpu_i386_kernel_restrict_flags(void) } static void -oil_cpu_i386_getflags(void) +oil_cpu_detect_i386(void) { -#ifdef __linux__ +#if 0 char *cpuinfo; cpuinfo = get_proc_cpuinfo(); @@ -299,16 +567,26 @@ oil_cpu_i386_getflags(void) } else { oil_cpu_i386_getflags_cpuid(); } -#else - oil_cpu_i386_getflags_cpuid(); #endif - oil_cpu_i386_kernel_restrict_flags(); -} + oil_cpu_detect_cpuid (); + oil_cpu_detect_kernel_support (); +} #endif + +/***** powerpc *****/ + #ifdef __powerpc__ +static unsigned long +oil_profile_stamp_tb(void) +{ + unsigned long ts; + __asm__ __volatile__("mftb %0\n" : "=r" (ts)); + return ts; +} + static void test_altivec (void * ignored) { @@ -320,7 +598,7 @@ test_altivec (void * ignored) } static void -oil_cpu_powerpc_getflags(void) +oil_cpu_detect_powerpc(void) { oil_cpu_fault_check_enable (); @@ -329,225 +607,164 @@ oil_cpu_powerpc_getflags(void) oil_cpu_flags |= OIL_IMPL_FLAG_ALTIVEC; } oil_cpu_fault_check_disable (); + + _oil_profile_stamp = oil_profile_stamp_tb; } #endif -void -_oil_cpu_init (void) + +/***** arm *****/ + +#ifdef __arm__ +static unsigned long +oil_profile_stamp_xscale(void) { - const char *envvar; + unsigned int ts; + __asm__ __volatile__ ( + " mrc p14, 0, %0, c0, c0, 0 \n" + : "=r" (ts)); + return ts; +} - envvar = getenv ("OIL_CPU_FLAGS"); - if (envvar != NULL) { - char *end = NULL; - unsigned long flags; +static void +oil_cpu_detect_arm(void) +{ +#ifdef __linux__ + int arm_implementer; + char *cpuinfo; - flags = strtoul (envvar, &end, 0); - if (end > envvar) { - oil_cpu_flags = flags; - } - OIL_INFO ("cpu flags from environment %08lx", oil_cpu_flags); - return; + cpuinfo = get_proc_cpuinfo(); + if (cpuinfo) { + oil_cpu_arm_getflags_cpuinfo(cpuinfo); } -#if defined(__i386__) || defined(__amd64__) - oil_cpu_i386_getflags(); + s = get_cpuinfo_tag(cpuinfo, "CPU implementer"); + if (s) { + arm_implementer = strtoul (s, NULL, 0); + } + + switch(arm_implementer) { + case 0x69: /* Intel */ + /* assume that all Intel chips support CP14 timestamp */ + _oil_profile_stamp = oil_profile_stamp_xscale255; + break; + case 0x41: /* ARM */ + /* ARM chips are known to not have timestamping available from + * user space */ + break; + default: + break; + } + + free (cpuinfo); #endif -#ifdef __powerpc__ - oil_cpu_powerpc_getflags(); +} #endif - OIL_INFO ("cpu flags %08lx", oil_cpu_flags); -} -/** - * oil_cpu_get_flags: - * - * Returns a bitmask containing the available CPU features. - * - * Returns: the CPU features. - */ -unsigned int -oil_cpu_get_flags (void) +/***** alpha *****/ + +#if defined(__alpha__) +static unsigned long +oil_profile_stamp_alpha(void) { - return oil_cpu_flags; + unsigned int ts; + __asm__ __volatile__ ("rpcc %0\n" : "=r"(ts)); + return ts; } -#if defined(__linux__) && (defined(__i386__) || defined(__amd64__)) -static char * -get_cpuinfo_flags_string (char *cpuinfo) +static void +oil_cpu_detect_alpha(void) { - char *flags; - char *end; - char *colon; - - flags = strstr(cpuinfo,"flags"); - if (flags == NULL) return NULL; - - end = strchr(flags, '\n'); - if (end == NULL) return NULL; - colon = strchr (flags, ':'); - if (colon == NULL) return NULL; - colon++; - if(colon >= end) return NULL; - - return _strndup (colon, end-colon); + _oil_profile_stamp = oil_profile_stamp_alpha; } +#endif +/***** ia64 *****/ -static char ** -strsplit (char *s) +#if defined(__ia64__) +static unsigned long +oil_profile_stamp_ia64(void) { - char **list = NULL; - char *tok; - int n = 0; - - while (*s == ' ') s++; - - list = malloc (1 * sizeof(char *)); - while (*s) { - tok = s; - while (*s && *s != ' ') s++; - - list[n] = _strndup (tok, s - tok); - while (*s && *s == ' ') s++; - list = realloc (list, (n + 2) * sizeof(char *)); - n++; - } - - list[n] = NULL; - return list; + unsigned int ts; + __asm__ __volatile__("mov %0=ar.itc\n" : "=r"(ts) :: "memory"); + return ts; } -static char * -_strndup (const char *s, int n) +static void +oil_cpu_detect_ia64(void) { - char *r; - r = malloc (n+1); - memcpy(r,s,n); - r[n]=0; - - return r; + _oil_profile_stamp = oil_profile_stamp_ia64; } #endif -static jmp_buf jump_env; -#ifdef HAVE_SIGACTION -static struct sigaction action; -static struct sigaction oldaction; -#else -static void * oldhandler; -#endif -static int in_try_block; -static int enable_level; +/***** s390 *****/ -static void -illegal_instruction_handler (int num) +#if defined(__s390__) +static unsigned long +oil_profile_stamp_s390(void) { - if (in_try_block) { - longjmp (jump_env, 1); - } else { - abort (); - } + uint64_t ts; + __asm__ __volatile__ ("STCK %0\n" : : "m" (ts)); + return ts; } -/** - * oil_cpu_fault_check_enable: - * - * Enables fault checking mode. This function may be called multiple times. - * Each call to this function must be paired with a corresponding call - * to oil_cpu_fault_check_disable(). - * - * This function sets a signal handler for SIGILL. - */ -void -oil_cpu_fault_check_enable (void) +static void +oil_cpu_detect_s390(void) { - if (enable_level == 0) { -#ifdef HAVE_SIGACTION - memset (&action, 0, sizeof(action)); - action.sa_handler = &illegal_instruction_handler; - sigaction (SIGILL, &action, &oldaction); -#else - oldhandler = signal (SIGILL, illegal_instruction_handler); -#endif - in_try_block = 0; - OIL_INFO("enabling SIGILL handler. Make sure to continue past " - "any SIGILL signals caught by gdb."); - } - enable_level++; + _oil_profile_stamp = oil_profile_stamp_s390; } +#endif -/** - * oil_cpu_fault_check_try: - * @func: the function to attempt - * @priv: a value to pass to the function - * - * Calls to this - * function must be preceded by a call to oil_cpu_fault_check_enable() - * to enable fault checking mode. This function sets up recovery - * information and then calls the function @func with the parameter - * @priv. If @func or any other functions it calls attempt to execute - * an illegal instruction, the exception will be caught and recovered from. - * - * Returns: 1 if the function was executed sucessfully, 0 if the - * function attempted to execute an illegal instruction. - */ -int -oil_cpu_fault_check_try (void (*func) (void *), void *priv) -{ - int ret; +/***** mips *****/ - in_try_block = 1; - ret = setjmp (jump_env); - if (!ret) { - func (priv); - } - in_try_block = 0; - - return (ret == 0); +#if defined(__mips__) +#if 0 +/* broken */ +static unsigned long +oil_profile_stamp_mips(void) +{ + unsigned int ts; + __asm__ __volatile__ ( + " .set push \n" + " .set reorder \n" + " mfc0 %0,$9 \n" + " .set pop \n" + : "=m" (ts)); + return ts; } +#endif -/** - * oil_cpu_fault_check_disable: - * - * Disables fault checking mode. See oil_cpu_fault_check_enable() - * for details. - */ -void -oil_cpu_fault_check_disable (void) +static void +oil_cpu_detect_mips(void) { - enable_level--; - if (enable_level == 0) { -#ifdef HAVE_SIGACTION - sigaction (SIGILL, &oldaction, NULL); -#else - signal (SIGILL, oldhandler); -#endif - OIL_INFO("disabling SIGILL handler"); - } + //_oil_profile_stamp = oil_profile_stamp_mips; } +#endif -#if 0 -/** - * oil_cpu_get_ticks_per_second: - * - * Returns the estimated number of ticks per second. This feature - * is currently unimplemented. - * - * This function may take several milliseconds or more to execute - * in order to calculate a good estimate of the number of ticks (as - * measured by the profiling functions) per second. Note that the - * number of ticks per second is often dependent on the CPU frequency, - * which can change dynamically. Thus the value returned by this - * function may be incorrect as soon as it is returned. - * - * Returns: a double - */ -double -oil_cpu_get_ticks_per_second (void) +static void +oil_cpu_detect_arch(void) { - return _oil_ticks_per_second; -} +#ifdef __i386__ + oil_cpu_detect_i386(); +#endif +#ifdef __powerpc__ + oil_cpu_detect_powerpc(); +#endif +#ifdef __arm__ + oil_cpu_detect_arm(); +#endif +#ifdef __alpha__ + oil_cpu_detect_alpha(); +#endif +#ifdef __ia64__ + oil_cpu_detect_ia64(); #endif +#ifdef __s390__ + oil_cpu_detect_s390(); +#endif +#ifdef __mips__ + oil_cpu_detect_mips(); +#endif +} diff --git a/liboil/liboildebug.c b/liboil/liboildebug.c index be62cc7..68e9f1f 100644 --- a/liboil/liboildebug.c +++ b/liboil/liboildebug.c @@ -64,7 +64,7 @@ _oil_debug_init(void) } } - OIL_INFO ("debug init"); + OIL_INFO ("liboil-" VERSION " debug init"); } static void diff --git a/liboil/liboilfunction.c b/liboil/liboilfunction.c index 310225e..1484e6c 100644 --- a/liboil/liboilfunction.c +++ b/liboil/liboilfunction.c @@ -41,16 +41,6 @@ * SECTION:liboilclass-unstable * @title:OilFunctionClass * @short_description: Functions for manipulating function classes - */ - -/** - * SECTION:liboilimpl-unstable - * @title:OilFunctionImpl - * @short_description: Functions for manipulating function implementations. - */ - -/** - * liboilfunction:long_description: * * <para> * Functions operate on arrays of data. The arrays can be either source @@ -94,6 +84,12 @@ * </para> */ +/** + * SECTION:liboilimpl-unstable + * @title:OilFunctionImpl + * @short_description: Functions for manipulating function implementations. + */ + extern OilFunctionClass *_oil_function_class_array[]; extern OilFunctionImpl *_oil_function_impl_array[]; @@ -106,7 +102,6 @@ static void oil_init_structs (void); static char * xstrdup (const char *s); void _oil_cpu_init (void); -void _oil_profile_init (void); /** * SECTION:liboilinit @@ -139,7 +134,6 @@ oil_init (void) _oil_debug_init (); _oil_cpu_init (); - _oil_profile_init (); oil_init_pointers (); oil_init_structs (); @@ -165,7 +159,6 @@ oil_init_no_optimize (void) _oil_debug_init (); _oil_cpu_init (); - _oil_profile_init (); oil_init_pointers (); oil_init_structs (); } diff --git a/liboil/liboilprofile.c b/liboil/liboilprofile.c index 957a0bb..f84fcb2 100644 --- a/liboil/liboilprofile.c +++ b/liboil/liboilprofile.c @@ -146,105 +146,7 @@ oil_profile_get_ave_std (OilProfile *prof, double *ave_p, double *std_p) if (std_p) *std_p = std; } - - -#if defined(__i386__) || defined(__amd64__) -static unsigned long -oil_profile_stamp_tsc(void) -{ - unsigned long ts; - __asm__ __volatile__("rdtsc\n" : "=a" (ts) : : "edx"); - return ts; -} -#endif - -#if defined(__powerpc__) -static unsigned long -oil_profile_stamp_tb(void) -{ - unsigned long ts; - __asm__ __volatile__("mftb %0\n" : "=r" (ts)); - return ts; -} -#endif - -#if defined(__alpha__) -static unsigned long -oil_profile_stamp_counter(void) -{ - unsigned int ts; - __asm__ __volatile__ ("rpcc %0\n" : "=r"(ts)); - return ts; -} -#endif - -#if defined(__ia64__) -static unsigned long -oil_profile_stamp_counter(void) -{ - unsigned int ts; - __asm__ __volatile__("mov %0=ar.itc\n" : "=r"(ts) :: "memory"); - return ts; -} -#endif - -#if defined(__s390__) -static unsigned long -oil_profile_stamp_counter(void) -{ - uint64_t ts; - __asm__ __volatile__ ("STCK %0\n" : : "m" (ts)); - return ts; -} -#endif - -#if defined(__mips__) && 0 -/* broken */ -static unsigned long -oil_profile_stamp_mips(void) -{ - unsigned int ts; - __asm__ __volatile__ ( - " .set push \n" - " .set reorder \n" - " mfc0 %0,$9 \n" - " .set pop \n" - : "=m" (ts)); - return ts; -} -#endif - -#if defined(__arm__) -/* untested */ -static unsigned long -oil_profile_stamp_xscale255(void) -{ - unsigned int ts; - /* this only works for XScale 255 */ - __asm__ __volatile__ ( - " mrc p14, 0, %0, c0, c0, 0 \n" - : "=r" (ts)); - return ts; -} -#endif - -#ifdef HAVE_GETTIMEOFDAY -static unsigned long -oil_profile_stamp_gtod (void) -{ - struct timeval tv; - gettimeofday(&tv,NULL); - return 1000000*(unsigned long)tv.tv_sec + (unsigned long)tv.tv_usec; -} -#endif - -static unsigned long -oil_profile_stamp_zero (void) -{ - return 0; -} - -static unsigned long (*_oil_profile_stamp)(void); +unsigned long (*_oil_profile_stamp)(void); /** * oil_profile_stamp: @@ -260,69 +162,3 @@ oil_profile_stamp (void) return _oil_profile_stamp(); } -void -_oil_profile_init (void) -{ - int gtod_warn = 1; - -#if defined(__i386__) -#define have_tsc 1 - if (have_tsc) { - _oil_profile_stamp = oil_profile_stamp_tsc; - } -#endif -#if defined(__amd64__) - _oil_profile_stamp = oil_profile_stamp_tsc; -#endif -#if defined(__powerpc__) - _oil_profile_stamp = oil_profile_stamp_tb; -#endif -#if defined(__alpha__) - _oil_profile_stamp = oil_profile_stamp_counter; -#endif -#if defined(__ia64__) - _oil_profile_stamp = oil_profile_stamp_counter; -#endif -#if defined(__s390__) - _oil_profile_stamp = oil_profile_stamp_counter; -#endif -#if defined(__mips__) && 0 - _oil_profile_stamp = oil_profile_stamp_mips; -#endif -#if defined(__arm__) - { - unsigned int id; - __asm__ __volatile__ ( - " mrc p15, 0, %0, c0, c0, 0 \n" - : "=r" (id)); - switch(id >> 24) { - case 0x69: /* Intel */ - /* assume that all Intel chips support CP14 timestamp */ - _oil_profile_stamp = oil_profile_stamp_xscale255; - break; - case 0x41: /* ARM */ - /* ARM chips are known to not have timestamping available from - * user space */ - gtod_warn = 0; - break; - default: - break; - } - } -#endif - -#ifdef HAVE_GETTIMEOFDAY - if (_oil_profile_stamp == NULL) { - _oil_profile_stamp = oil_profile_stamp_gtod; - if (gtod_warn) { - OIL_ERROR("Using gettimeofday() as a timestamp function. Please add a timestamp function for your platform."); - } - } -#endif - - if (_oil_profile_stamp == NULL) { - _oil_profile_stamp = oil_profile_stamp_zero; - OIL_ERROR("No timestamping function. This is kinda bad."); - } -} - |