mmtimer.c

Go to the documentation of this file.
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() */
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1