00001 /* 00002 * See the dyninst/COPYRIGHT file for copyright information. 00003 * 00004 * We provide the Paradyn Tools (below described as "Paradyn") 00005 * on an AS IS basis, and do not warrant its validity or performance. 00006 * We reserve the right to update, modify, or discontinue this 00007 * software at any time. We shall have no obligation to supply such 00008 * updates or modifications or any other form of support to you. 00009 * 00010 * By your use of Paradyn, you understand and agree that we (or any 00011 * other person or entity with proprietary rights in Paradyn) are 00012 * under no obligation to provide either maintenance services, 00013 * update services, notices of latent defects, or correction of 00014 * defects for Paradyn. 00015 * 00016 * This library is free software; you can redistribute it and/or 00017 * modify it under the terms of the GNU Lesser General Public 00018 * License as published by the Free Software Foundation; either 00019 * version 2.1 of the License, or (at your option) any later version. 00020 * 00021 * This library is distributed in the hope that it will be useful, 00022 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00024 * Lesser General Public License for more details. 00025 * 00026 * You should have received a copy of the GNU Lesser General Public 00027 * License along with this library; if not, write to the Free Software 00028 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00029 */ 00030 00031 #include <sn/mmtimer.h> /* MMTIMER_* */ 00032 00033 /* getpid() */ 00034 #include <sys/types.h> 00035 #include <unistd.h> 00036 00037 #include <stdio.h> /* fprintf() */ 00038 #include <sys/ioctl.h> /* for ioctl() */ 00039 #include <sys/mman.h> /* for mmap() */ 00040 00041 /* The mmtimer, once initialized by a call to isMMTimerAvail(), 00042 is always (mmdev_clicks_per_tick * (*mmdev_timer_addr)). */ 00043 static unsigned long mmdev_clicks_per_tick = 0; 00044 static volatile unsigned long * mmdev_timer_addr = NULL; 00045 00046 /* The defined interface in common/h/timing.h is too clumsy, so duplicate code. */ 00047 double getLocalCyclesPerSecond() { 00048 FILE * cpuinfo = fopen( "/proc/cpuinfo", "r" ); 00049 if( cpuinfo == NULL ) { return 0; } 00050 00051 double MHz = 0.0; 00052 /* Scan /proc/cpuinfo until we find something; assume all CPUs the same. */ 00053 while( ! feof( cpuinfo ) ) { 00054 char buffer[ 256 ]; 00055 char * result = fgets( buffer, 255, cpuinfo ); 00056 if( result != NULL ) { 00057 int status = sscanf( result, "cpu MHz : %lf", & MHz ); 00058 if( status == 1 ) { 00059 fclose( cpuinfo ); 00060 return ( MHz * 1000000.0 ); 00061 } 00062 } 00063 } /* end scanning loop */ 00064 00065 fclose( cpuinfo ); 00066 return 0; 00067 } /* end getLocalCyclesPerSecond() */ 00068 00069 int isMMTimerAvail() { 00070 int fd = 0; 00071 unsigned long femtosecondsPerTick = 0; 00072 int mmTimerOffset = 0; 00073 00074 /* Don't do anything twice. */ 00075 if( mmdev_clicks_per_tick != 0 || mmdev_timer_addr != 0 ) { return 1; } 00076 00077 /* Attempt to setup the mmtimer. */ 00078 if( ( fd = open( MMTIMER_FULLNAME, O_RDONLY ) ) == -1 ) { 00079 return 0; 00080 } 00081 if( ( mmTimerOffset = ioctl( fd, MMTIMER_GETOFFSET, 0 ) ) == -ENOSYS ) { 00082 close( fd ); 00083 return 0; 00084 } 00085 if( ( mmdev_timer_addr = (volatile unsigned long int *)mmap( 0, getpagesize(), PROT_READ, MAP_SHARED, fd, 0 ) ) == NULL ) { 00086 close( fd ); 00087 return 0; 00088 } 00089 00090 mmdev_timer_addr += mmTimerOffset; 00091 ioctl( fd, MMTIMER_GETRES, & femtosecondsPerTick ); 00092 mmdev_clicks_per_tick = (unsigned long)((getLocalCyclesPerSecond() * 1.0e-15) * femtosecondsPerTick); 00093 00094 assert( mmdev_clicks_per_tick != 0 ); 00095 00096 ///* DEBUG */ fprintf( stderr, "%d: %lf MHz, " 00097 // "microseconds/tick = %lf, " 00098 // "clicks_per_tick = %lu\n", 00099 // getpid(), 00100 // getLocalCyclesPerSecond() / 1.0e6, 00101 // femtosecondsPerTick / 1.0e9, 00102 // mmdev_clicks_per_tick ); 00103 00104 close( fd ); 00105 return 1; 00106 } /* end isMMtimerAvail() */
1.6.1