sl@0: /* sl@0: * LIBOIL - Library of Optimized Inner Loops sl@0: * Copyright (c) 2003,2004 David A. Schleef sl@0: * All rights reserved. sl@0: * sl@0: * Redistribution and use in source and binary forms, with or without sl@0: * modification, are permitted provided that the following conditions sl@0: * are met: sl@0: * 1. Redistributions of source code must retain the above copyright sl@0: * notice, this list of conditions and the following disclaimer. sl@0: * 2. Redistributions in binary form must reproduce the above copyright sl@0: * notice, this list of conditions and the following disclaimer in the sl@0: * documentation and/or other materials provided with the distribution. sl@0: * sl@0: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR sl@0: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED sl@0: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE sl@0: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, sl@0: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES sl@0: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR sl@0: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) sl@0: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, sl@0: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING sl@0: * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE sl@0: * POSSIBILITY OF SUCH DAMAGE. sl@0: */ sl@0: //Portions Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. sl@0: sl@0: #ifdef HAVE_CONFIG_H sl@0: #include "config.h" sl@0: #endif sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #ifdef HAVE_UNISTD_H sl@0: #include sl@0: #endif sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #ifdef HAVE_SYS_TIME_H sl@0: #include sl@0: #endif sl@0: #include sl@0: sl@0: #if defined(__FreeBSD__) sl@0: #include sl@0: #include sl@0: #endif sl@0: sl@0: #ifdef __sun sl@0: #include sl@0: #endif sl@0: sl@0: sl@0: sl@0: /** sl@0: * SECTION:liboilcpu sl@0: * @title: CPU sl@0: * @short_description: Check the capabilities of the current CPU sl@0: * sl@0: */ sl@0: sl@0: //void oil_cpu_detect_arch(void); sl@0: sl@0: unsigned long oil_cpu_flags; sl@0: sl@0: extern unsigned long (*_oil_profile_stamp)(void); sl@0: sl@0: #ifdef HAVE_GETTIMEOFDAY sl@0: static unsigned long sl@0: oil_profile_stamp_gtod (void) sl@0: { sl@0: struct timeval tv; sl@0: gettimeofday(&tv,NULL); sl@0: return 1000000*(unsigned long)tv.tv_sec + (unsigned long)tv.tv_usec; sl@0: } sl@0: #endif sl@0: sl@0: #if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_MONOTONIC_CLOCK) sl@0: static unsigned long sl@0: oil_profile_stamp_clock_gettime (void) sl@0: { sl@0: struct timespec ts; sl@0: clock_gettime (CLOCK_MONOTONIC, &ts); sl@0: return 1000000000*ts.tv_sec + ts.tv_nsec; sl@0: } sl@0: #endif sl@0: sl@0: static unsigned long sl@0: oil_profile_stamp_zero (void) sl@0: { sl@0: return 0; sl@0: } sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: sl@0: #endif sl@0: void sl@0: _oil_cpu_init (void) sl@0: { sl@0: const char *envvar; sl@0: sl@0: oil_cpu_detect_arch(); sl@0: sl@0: envvar = getenv ("OIL_CPU_FLAGS"); sl@0: if (envvar != NULL) { sl@0: char *end = NULL; sl@0: unsigned long flags; sl@0: sl@0: flags = strtoul (envvar, &end, 0); sl@0: if (end > envvar) { sl@0: oil_cpu_flags = flags; sl@0: } sl@0: OIL_INFO ("cpu flags from environment %08lx", oil_cpu_flags); sl@0: } sl@0: sl@0: OIL_INFO ("cpu flags %08lx", oil_cpu_flags); sl@0: sl@0: #if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_MONOTONIC_CLOCK) sl@0: if (_oil_profile_stamp == NULL) { sl@0: _oil_profile_stamp = oil_profile_stamp_clock_gettime; sl@0: OIL_INFO("Using clock_gettime() as a timestamp function."); sl@0: } sl@0: #endif sl@0: sl@0: #ifdef HAVE_GETTIMEOFDAY sl@0: if (_oil_profile_stamp == NULL) { sl@0: _oil_profile_stamp = oil_profile_stamp_gtod; sl@0: OIL_WARNING("Using gettimeofday() as a timestamp function."); sl@0: } sl@0: #endif sl@0: if (_oil_profile_stamp == NULL) { sl@0: _oil_profile_stamp = oil_profile_stamp_zero; sl@0: OIL_ERROR("No timestamping function. This is kinda bad."); sl@0: } sl@0: } sl@0: sl@0: /** sl@0: * oil_cpu_get_flags: sl@0: * sl@0: * Returns a bitmask containing the available CPU features. sl@0: * sl@0: * Returns: the CPU features. sl@0: */ sl@0: #ifdef __SYMBIAN32__ sl@0: EXPORT_C sl@0: #endif sl@0: unsigned int sl@0: oil_cpu_get_flags (void) sl@0: { sl@0: return oil_cpu_flags; sl@0: } sl@0: sl@0: sl@0: #if 0 sl@0: /** sl@0: * oil_cpu_get_ticks_per_second: sl@0: * sl@0: * Returns the estimated number of ticks per second. This feature sl@0: * is currently unimplemented. sl@0: * sl@0: * This function may take several milliseconds or more to execute sl@0: * in order to calculate a good estimate of the number of ticks (as sl@0: * measured by the profiling functions) per second. Note that the sl@0: * number of ticks per second is often dependent on the CPU frequency, sl@0: * which can change dynamically. Thus the value returned by this sl@0: * function may be incorrect as soon as it is returned. sl@0: * sl@0: * Returns: a double sl@0: */ sl@0: double sl@0: oil_cpu_get_ticks_per_second (void) sl@0: { sl@0: return _oil_ticks_per_second; sl@0: } sl@0: #endif sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: EXPORT_C sl@0: #endif sl@0: double sl@0: oil_cpu_get_frequency (void) sl@0: { sl@0: #if defined(__linux__) sl@0: int freq; sl@0: if (get_file_int ("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq", sl@0: &freq)) { sl@0: return 1000.0 * freq; sl@0: } sl@0: return 0; sl@0: #else sl@0: return 0; sl@0: #endif sl@0: } sl@0: