PAPI  5.0.1.0
linux-common.c
Go to the documentation of this file.
00001 /*
00002 * File:    linux-common.c
00003 */
00004 
00005 #include <unistd.h>
00006 #include <string.h>
00007 #include <stdlib.h>
00008 #include <ctype.h>
00009 #include <err.h>
00010 #include <stdarg.h>
00011 #include <stdio.h>
00012 #include <errno.h>
00013 #include <syscall.h>
00014 #include <sys/utsname.h>
00015 #include <sys/time.h>
00016 
00017 #include "papi.h"
00018 #include "papi_internal.h"
00019 #include "papi_vector.h"
00020 
00021 #include "linux-memory.h"
00022 #include "linux-common.h"
00023 #include "linux-timer.h"
00024 
00025 #include "x86_cpuid_info.h"
00026 
00027 PAPI_os_info_t _papi_os_info;
00028 
00029 /* The locks used by Linux */
00030 
00031 #if defined(USE_PTHREAD_MUTEXES)
00032 pthread_mutex_t _papi_hwd_lock_data[PAPI_MAX_LOCK];
00033 #else
00034 volatile unsigned int _papi_hwd_lock_data[PAPI_MAX_LOCK];
00035 #endif
00036 
00037 
00038 static int _linux_init_locks(void) {
00039 
00040    int i;
00041 
00042    for ( i = 0; i < PAPI_MAX_LOCK; i++ ) {
00043 #if defined(USE_PTHREAD_MUTEXES)
00044        pthread_mutex_init(&_papi_hwd_lock_data[i],NULL);
00045 #else
00046        _papi_hwd_lock_data[i] = MUTEX_OPEN;
00047 #endif
00048    }
00049 
00050    return PAPI_OK;
00051 }
00052 
00053     
00054 int
00055 _linux_detect_hypervisor(char *virtual_vendor_name) {
00056 
00057     int retval=0;
00058 
00059 #if defined(__i386__)||defined(__x86_64__)
00060     retval=_x86_detect_hypervisor(virtual_vendor_name);
00061 #else
00062     (void) virtual_vendor_name;
00063 #endif
00064     
00065     return retval;
00066 }
00067 
00068 
00069 #define _PATH_SYS_SYSTEM "/sys/devices/system"
00070 #define _PATH_SYS_CPU0   _PATH_SYS_SYSTEM "/cpu/cpu0"
00071 
00072 static char pathbuf[PATH_MAX] = "/";
00073 
00074 
00075 static char *
00076 search_cpu_info( FILE * f, char *search_str, char *line )
00077 {
00078     /* This function courtesy of Rudolph Berrendorf! */
00079     /* See the home page for the German version of PAPI. */
00080     char *s;
00081 
00082     while ( fgets( line, 256, f ) != NULL ) {
00083         if ( strstr( line, search_str ) != NULL ) {
00084             /* ignore all characters in line up to : */
00085             for ( s = line; *s && ( *s != ':' ); ++s );
00086             if ( *s )
00087                 return s;
00088         }
00089     }
00090     return NULL;
00091 }
00092 
00093 static void
00094 decode_vendor_string( char *s, int *vendor )
00095 {
00096     if ( strcasecmp( s, "GenuineIntel" ) == 0 )
00097         *vendor = PAPI_VENDOR_INTEL;
00098     else if ( ( strcasecmp( s, "AMD" ) == 0 ) ||
00099               ( strcasecmp( s, "AuthenticAMD" ) == 0 ) )
00100         *vendor = PAPI_VENDOR_AMD;
00101     else if ( strcasecmp( s, "IBM" ) == 0 )
00102         *vendor = PAPI_VENDOR_IBM;
00103     else if ( strcasecmp( s, "Cray" ) == 0 )
00104         *vendor = PAPI_VENDOR_CRAY;
00105     else if ( strcasecmp( s, "ARM" ) == 0 )
00106         *vendor = PAPI_VENDOR_ARM;
00107     else if ( strcasecmp( s, "MIPS" ) == 0 )
00108         *vendor = PAPI_VENDOR_MIPS;
00109     else if ( strcasecmp( s, "SiCortex" ) == 0 )
00110         *vendor = PAPI_VENDOR_MIPS;
00111     else
00112         *vendor = PAPI_VENDOR_UNKNOWN;
00113 }
00114 
00115 static FILE *
00116 xfopen( const char *path, const char *mode )
00117 {
00118     FILE *fd = fopen( path, mode );
00119     if ( !fd )
00120         err( EXIT_FAILURE, "error: %s", path );
00121     return fd;
00122 }
00123 
00124 static FILE *
00125 path_vfopen( const char *mode, const char *path, va_list ap )
00126 {
00127     vsnprintf( pathbuf, sizeof ( pathbuf ), path, ap );
00128     return xfopen( pathbuf, mode );
00129 }
00130 
00131 
00132 static int
00133 path_sibling( const char *path, ... )
00134 {
00135     int c;
00136     long n;
00137     int result = 0;
00138     char s[2];
00139     FILE *fp;
00140     va_list ap;
00141     va_start( ap, path );
00142     fp = path_vfopen( "r", path, ap );
00143     va_end( ap );
00144 
00145     while ( ( c = fgetc( fp ) ) != EOF ) {
00146         if ( isxdigit( c ) ) {
00147             s[0] = ( char ) c;
00148             s[1] = '\0';
00149             for ( n = strtol( s, NULL, 16 ); n > 0; n /= 2 ) {
00150                 if ( n % 2 )
00151                     result++;
00152             }
00153         }
00154     }
00155 
00156     fclose( fp );
00157     return result;
00158 }
00159 
00160 static int
00161 path_exist( const char *path, ... )
00162 {
00163     va_list ap;
00164     va_start( ap, path );
00165     vsnprintf( pathbuf, sizeof ( pathbuf ), path, ap );
00166     va_end( ap );
00167     return access( pathbuf, F_OK ) == 0;
00168 }
00169 
00170 int
00171 _linux_get_cpu_info( PAPI_hw_info_t *hwinfo, int *cpuinfo_mhz )
00172 {
00173     int tmp, retval = PAPI_OK;
00174     char maxargs[PAPI_HUGE_STR_LEN], *t, *s;
00175     float mhz = 0.0;
00176     FILE *f;
00177 
00178     if ( ( f = fopen( "/proc/cpuinfo", "r" ) ) == NULL ) {
00179        PAPIERROR( "fopen(/proc/cpuinfo) errno %d", errno );
00180        return PAPI_ESYS;
00181     }
00182 
00183     /* All of this information maybe overwritten by the component */
00184 
00185         /* MHZ */
00186     rewind( f );
00187     s = search_cpu_info( f, "clock", maxargs );
00188     if ( !s ) {
00189        rewind( f );
00190        s = search_cpu_info( f, "cpu MHz", maxargs );
00191     }
00192     if ( s ) {
00193        sscanf( s + 1, "%f", &mhz );
00194     }
00195     *cpuinfo_mhz = mhz;
00196 
00197        /* Vendor Name and Vendor Code */
00198     rewind( f );
00199     s = search_cpu_info( f, "vendor_id", maxargs );
00200     if ( s && ( t = strchr( s + 2, '\n' ) ) ) {
00201        *t = '\0';
00202        strcpy( hwinfo->vendor_string, s + 2 );
00203     } else {
00204        rewind( f );
00205        s = search_cpu_info( f, "vendor", maxargs );
00206        if ( s && ( t = strchr( s + 2, '\n' ) ) ) {
00207       *t = '\0';
00208       strcpy( hwinfo->vendor_string, s + 2 );
00209        } else {
00210       rewind( f );
00211       s = search_cpu_info( f, "system type", maxargs );
00212       if ( s && ( t = strchr( s + 2, '\n' ) ) ) {
00213          *t = '\0';
00214          s = strtok( s + 2, " " );
00215          strcpy( hwinfo->vendor_string, s );
00216       } else {
00217          rewind( f );
00218          s = search_cpu_info( f, "platform", maxargs );
00219          if ( s && ( t = strchr( s + 2, '\n' ) ) ) {
00220         *t = '\0';
00221             s = strtok( s + 2, " " );
00222         if ( ( strcasecmp( s, "pSeries" ) == 0 ) ||
00223              ( strcasecmp( s, "PowerMac" ) == 0 ) ) {
00224            strcpy( hwinfo->vendor_string, "IBM" );
00225         }
00226          } else {
00227         rewind( f );
00228         s = search_cpu_info( f, "CPU implementer", maxargs );
00229         if ( s ) {
00230            strcpy( hwinfo->vendor_string, "ARM" );
00231         }
00232          }          
00233       }
00234        }
00235     }
00236     
00237     if ( strlen( hwinfo->vendor_string ) ) {
00238        decode_vendor_string( hwinfo->vendor_string, &hwinfo->vendor );
00239     }
00240 
00241     /* Revision */
00242     rewind( f );
00243     s = search_cpu_info( f, "stepping", maxargs );
00244     if ( s ) {
00245        sscanf( s + 1, "%d", &tmp );
00246        hwinfo->revision = ( float ) tmp;
00247        hwinfo->cpuid_stepping = tmp;
00248     } else {
00249        rewind( f );
00250        s = search_cpu_info( f, "revision", maxargs );
00251        if ( s ) {
00252       sscanf( s + 1, "%d", &tmp );
00253       hwinfo->revision = ( float ) tmp;
00254       hwinfo->cpuid_stepping = tmp;
00255        }
00256     }
00257 
00258        /* Model Name */
00259     rewind( f );
00260     s = search_cpu_info( f, "model name", maxargs );
00261     if ( s && ( t = strchr( s + 2, '\n' ) ) ) {
00262        *t = '\0';
00263        strcpy( hwinfo->model_string, s + 2 );
00264     } else {
00265        rewind( f );
00266        s = search_cpu_info( f, "family", maxargs );
00267        if ( s && ( t = strchr( s + 2, '\n' ) ) ) {
00268       *t = '\0';
00269       strcpy( hwinfo->model_string, s + 2 );
00270        } else {
00271       rewind( f );
00272       s = search_cpu_info( f, "cpu model", maxargs );
00273       if ( s && ( t = strchr( s + 2, '\n' ) ) ) {
00274          *t = '\0';
00275          strtok( s + 2, " " );
00276          s = strtok( NULL, " " );
00277          strcpy( hwinfo->model_string, s );
00278       } else {
00279          rewind( f );
00280          s = search_cpu_info( f, "cpu", maxargs );
00281          if ( s && ( t = strchr( s + 2, '\n' ) ) ) {
00282         *t = '\0';
00283         /* get just the first token */
00284         s = strtok( s + 2, " " );
00285         strcpy( hwinfo->model_string, s );
00286          }
00287       }
00288        }
00289     }
00290 
00291        /* Family */
00292     rewind( f );
00293     s = search_cpu_info( f, "family", maxargs );
00294     if ( s ) {
00295        sscanf( s + 1, "%d", &tmp );
00296        hwinfo->cpuid_family = tmp;
00297     } else {
00298        rewind( f );
00299        s = search_cpu_info( f, "cpu family", maxargs );
00300        if ( s ) {
00301       sscanf( s + 1, "%d", &tmp );
00302       hwinfo->cpuid_family = tmp;
00303     }
00304     }
00305 
00306     /* CPU Model */
00307     rewind( f );
00308     s = search_cpu_info( f, "model", maxargs );
00309     if ( s ) {
00310        sscanf( s + 1, "%d", &tmp );
00311        hwinfo->model = tmp;
00312        hwinfo->cpuid_model = tmp;
00313     }
00314 
00315 
00316     /* The following members are set using the same methodology */
00317     /* used in lscpu.                                           */
00318 
00319     /* Total number of CPUs */
00320     /* The following line assumes totalcpus was initialized to zero! */
00321     while ( path_exist( _PATH_SYS_SYSTEM "/cpu/cpu%d", hwinfo->totalcpus ) )
00322         hwinfo->totalcpus++;
00323 
00324     /* Number of threads per core */
00325     if ( path_exist( _PATH_SYS_CPU0 "/topology/thread_siblings" ) )
00326         hwinfo->threads =
00327             path_sibling( _PATH_SYS_CPU0 "/topology/thread_siblings" );
00328 
00329     /* Number of cores per socket */
00330     if ( path_exist( _PATH_SYS_CPU0 "/topology/core_siblings" ) &&
00331          hwinfo->threads > 0 )
00332         hwinfo->cores =
00333             path_sibling( _PATH_SYS_CPU0 "/topology/core_siblings" ) /
00334             hwinfo->threads;
00335 
00336     /* Number of sockets */
00337     if ( hwinfo->threads > 0 && hwinfo->cores > 0 )
00338         hwinfo->sockets = hwinfo->ncpu / hwinfo->cores / hwinfo->threads;
00339 
00340     /* Number of NUMA nodes */
00341     /* The following line assumes nnodes was initialized to zero! */
00342     while ( path_exist( _PATH_SYS_SYSTEM "/node/node%d", hwinfo->nnodes ) )
00343         hwinfo->nnodes++;
00344 
00345     /* Number of CPUs per node */
00346     hwinfo->ncpu =
00347         hwinfo->nnodes >
00348         1 ? hwinfo->totalcpus / hwinfo->nnodes : hwinfo->totalcpus;
00349 #if 0
00350     int *nodecpu;
00351     /* cpumap data is not currently part of the _papi_hw_info struct */
00352         nodecpu = malloc( (unsigned int) hwinfo->nnodes * sizeof(int) );
00353     if ( nodecpu ) {
00354        int i;
00355        for ( i = 0; i < hwinfo->nnodes; ++i ) {
00356            nodecpu[i] = path_sibling( 
00357                              _PATH_SYS_SYSTEM "/node/node%d/cpumap", i );
00358        }
00359     } else {
00360         PAPIERROR( "malloc failed for variable not currently used" );
00361     }
00362 #endif
00363 
00364 
00365     /* Fixup missing Megahertz Value */
00366     /* This is missing from cpuinfo on ARM and MIPS */
00367      if (*cpuinfo_mhz < 1.0) {
00368     rewind( f );
00369     
00370     s = search_cpu_info( f, "BogoMIPS", maxargs );
00371     if ((!s) || (sscanf( s + 1, "%f", &mhz ) != 1)) {
00372        PAPIERROR("Mhz detection failed. Please edit file %s at line %d.\n",
00373              __FILE__,__LINE__);
00374     }
00375 
00376     if (hwinfo->vendor == PAPI_VENDOR_MIPS) {
00377         /* MIPS has 2x clock multiplier */
00378         *cpuinfo_mhz = 2*(((int)mhz)+1);
00379     
00380         /* Also update version info on MIPS */
00381         rewind( f );
00382         s = search_cpu_info( f, "cpu model", maxargs );
00383         s = strstr(s+1," V")+2;
00384          strtok(s," ");
00385         sscanf(s, "%f ", &hwinfo->revision );
00386     }
00387     else {
00388         /* In general bogomips is proportional to number of CPUs */
00389         if (hwinfo->totalcpus) {
00390            *cpuinfo_mhz = mhz / hwinfo->totalcpus;
00391         }
00392     }
00393      }
00394 
00395     fclose( f );
00396 
00397     return retval;
00398 }
00399 
00400 int
00401 _linux_get_mhz( int *sys_min_mhz, int *sys_max_mhz ) {
00402 
00403   FILE *fff;
00404   int result;
00405 
00406   /* Try checking for min MHz */
00407   /* Assume cpu0 exists */
00408   fff=fopen("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq","r");
00409   if (fff==NULL) return PAPI_EINVAL;
00410   result=fscanf(fff,"%d",sys_min_mhz);
00411   fclose(fff);
00412   if (result!=1) return PAPI_EINVAL;
00413 
00414   fff=fopen("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq","r");
00415   if (fff==NULL) return PAPI_EINVAL;
00416   result=fscanf(fff,"%d",sys_max_mhz);
00417   fclose(fff);
00418   if (result!=1) return PAPI_EINVAL;
00419 
00420   return PAPI_OK;
00421 
00422 }
00423 
00424 int
00425 _linux_get_system_info( papi_mdi_t *mdi ) {
00426 
00427     int retval;
00428 
00429     char maxargs[PAPI_HUGE_STR_LEN];
00430     pid_t pid;
00431 
00432     int cpuinfo_mhz,sys_min_khz,sys_max_khz;
00433 
00434     /* Software info */
00435 
00436     /* Path and args */
00437 
00438     pid = getpid(  );
00439     if ( pid < 0 ) {
00440         PAPIERROR( "getpid() returned < 0" );
00441         return PAPI_ESYS;
00442     }
00443     mdi->pid = pid;
00444 
00445     sprintf( maxargs, "/proc/%d/exe", ( int ) pid );
00446     if ( readlink( maxargs, mdi->exe_info.fullname, PAPI_HUGE_STR_LEN ) < 0 ) {
00447         PAPIERROR( "readlink(%s) returned < 0", maxargs );
00448         return PAPI_ESYS;
00449     }
00450 
00451     /* Careful, basename can modify it's argument */
00452 
00453     strcpy( maxargs, mdi->exe_info.fullname );
00454     strcpy( mdi->exe_info.address_info.name, basename( maxargs ) );
00455 
00456     SUBDBG( "Executable is %s\n", mdi->exe_info.address_info.name );
00457     SUBDBG( "Full Executable is %s\n", mdi->exe_info.fullname );
00458 
00459     /* Executable regions, may require reading /proc/pid/maps file */
00460 
00461     retval = _linux_update_shlib_info( mdi );
00462     SUBDBG( "Text: Start %p, End %p, length %d\n",
00463             mdi->exe_info.address_info.text_start,
00464             mdi->exe_info.address_info.text_end,
00465             ( int ) ( mdi->exe_info.address_info.text_end -
00466                       mdi->exe_info.address_info.text_start ) );
00467     SUBDBG( "Data: Start %p, End %p, length %d\n",
00468             mdi->exe_info.address_info.data_start,
00469             mdi->exe_info.address_info.data_end,
00470             ( int ) ( mdi->exe_info.address_info.data_end -
00471                       mdi->exe_info.address_info.data_start ) );
00472     SUBDBG( "Bss: Start %p, End %p, length %d\n",
00473             mdi->exe_info.address_info.bss_start,
00474             mdi->exe_info.address_info.bss_end,
00475             ( int ) ( mdi->exe_info.address_info.bss_end -
00476                       mdi->exe_info.address_info.bss_start ) );
00477 
00478     /* PAPI_preload_option information */
00479 
00480     strcpy( mdi->preload_info.lib_preload_env, "LD_PRELOAD" );
00481     mdi->preload_info.lib_preload_sep = ' ';
00482     strcpy( mdi->preload_info.lib_dir_env, "LD_LIBRARY_PATH" );
00483     mdi->preload_info.lib_dir_sep = ':';
00484 
00485     /* Hardware info */
00486 
00487     retval = _linux_get_cpu_info( &mdi->hw_info, &cpuinfo_mhz );
00488     if ( retval )
00489         return retval;
00490 
00491     /* Handle MHz */
00492 
00493     retval = _linux_get_mhz( &sys_min_khz, &sys_max_khz );
00494     if ( retval ) {
00495 
00496        mdi->hw_info.cpu_max_mhz=cpuinfo_mhz;
00497        mdi->hw_info.cpu_min_mhz=cpuinfo_mhz;
00498 
00499        /*
00500        mdi->hw_info.mhz=cpuinfo_mhz;
00501        mdi->hw_info.clock_mhz=cpuinfo_mhz;
00502        */
00503     }
00504     else {
00505        mdi->hw_info.cpu_max_mhz=sys_max_khz/1000;
00506        mdi->hw_info.cpu_min_mhz=sys_min_khz/1000;
00507 
00508        /*
00509        mdi->hw_info.mhz=sys_max_khz/1000;
00510        mdi->hw_info.clock_mhz=sys_max_khz/1000;
00511        */
00512     }
00513 
00514     /* Set Up Memory */
00515 
00516     retval = _linux_get_memory_info( &mdi->hw_info, mdi->hw_info.model );
00517     if ( retval )
00518         return retval;
00519 
00520     SUBDBG( "Found %d %s(%d) %s(%d) CPUs at %d Mhz.\n",
00521             mdi->hw_info.totalcpus,
00522             mdi->hw_info.vendor_string,
00523             mdi->hw_info.vendor, 
00524                 mdi->hw_info.model_string, 
00525                 mdi->hw_info.model,
00526                 mdi->hw_info.cpu_max_mhz);
00527 
00528     /* Get virtualization info */
00529     mdi->hw_info.virtualized=_linux_detect_hypervisor(mdi->hw_info.virtual_vendor_string);
00530 
00531     return PAPI_OK;
00532 }
00533 
00534 int 
00535 _papi_hwi_init_os(void) {
00536 
00537     int major=0,minor=0,sub=0;
00538     char *ptr;
00539     struct utsname uname_buffer;
00540 
00541     /* Initialize the locks */
00542     _linux_init_locks();
00543 
00544     /* Get the kernel info */
00545     uname(&uname_buffer);
00546 
00547     SUBDBG("Native kernel version %s\n",uname_buffer.release);
00548 
00549     strncpy(_papi_os_info.name,uname_buffer.sysname,PAPI_MAX_STR_LEN);
00550 
00551 #ifdef ASSUME_KERNEL
00552     strncpy(_papi_os_info.version,ASSUME_KERNEL,PAPI_MAX_STR_LEN);
00553     SUBDBG("Assuming kernel version %s\n",_papi_os_info.name);
00554 #else
00555     strncpy(_papi_os_info.version,uname_buffer.release,PAPI_MAX_STR_LEN);
00556 #endif
00557 
00558     ptr=strtok(_papi_os_info.version,".");
00559     if (ptr!=NULL) major=atoi(ptr);
00560 
00561     ptr=strtok(NULL,".");
00562     if (ptr!=NULL) minor=atoi(ptr);
00563 
00564     ptr=strtok(NULL,".");
00565     if (ptr!=NULL) sub=atoi(ptr);
00566 
00567    _papi_os_info.os_version=LINUX_VERSION(major,minor,sub);
00568 
00569    _papi_os_info.itimer_sig = PAPI_INT_MPX_SIGNAL;
00570    _papi_os_info.itimer_num = PAPI_INT_ITIMER;
00571    _papi_os_info.itimer_ns = PAPI_INT_MPX_DEF_US * 1000;
00572    _papi_os_info.itimer_res_ns = 1;
00573    _papi_os_info.clock_ticks = sysconf( _SC_CLK_TCK );
00574 
00575    /* Get Linux-specific system info */
00576    _linux_get_system_info( &_papi_hwi_system_info );
00577 
00578    return PAPI_OK;
00579 }
00580 
00581 
00582 
00583 int _linux_detect_nmi_watchdog() {
00584 
00585   int watchdog_detected=0,watchdog_value=0;
00586   FILE *fff;
00587 
00588   fff=fopen("/proc/sys/kernel/nmi_watchdog","r");
00589   if (fff!=NULL) {
00590      if (fscanf(fff,"%d",&watchdog_value)==1) {
00591         if (watchdog_value>0) watchdog_detected=1;
00592      }
00593      fclose(fff);
00594   }
00595 
00596   return watchdog_detected;
00597 }
00598 
00599 papi_os_vector_t _papi_os_vector = {
00600   .get_memory_info =   _linux_get_memory_info,
00601   .get_dmem_info =     _linux_get_dmem_info,
00602   .get_real_cycles =   _linux_get_real_cycles,
00603   .update_shlib_info = _linux_update_shlib_info,
00604   .get_system_info =   _linux_get_system_info,
00605 
00606 
00607 #if defined(HAVE_CLOCK_GETTIME)
00608   .get_real_usec =  _linux_get_real_usec_gettime,
00609 #elif defined(HAVE_GETTIMEOFDAY)
00610   .get_real_usec =  _linux_get_real_usec_gettimeofday,
00611 #else
00612   .get_real_usec =  _linux_get_real_usec_cycles,
00613 #endif
00614 
00615 
00616 #if defined(USE_PROC_PTTIMER)
00617   .get_virt_usec =   _linux_get_virt_usec_pttimer,
00618 #elif defined(HAVE_CLOCK_GETTIME_THREAD)
00619   .get_virt_usec =   _linux_get_virt_usec_gettime,
00620 #elif defined(HAVE_PER_THREAD_TIMES)
00621   .get_virt_usec =   _linux_get_virt_usec_times,
00622 #elif defined(HAVE_PER_THREAD_GETRUSAGE)
00623   .get_virt_usec =   _linux_get_virt_usec_rusage,
00624 #endif
00625 
00626 
00627 #if defined(HAVE_CLOCK_GETTIME)
00628   .get_real_nsec =  _linux_get_real_nsec_gettime,
00629 #endif
00630 
00631 #if defined(HAVE_CLOCK_GETTIME_THREAD)
00632   .get_virt_nsec =   _linux_get_virt_nsec_gettime,
00633 #endif
00634 
00635 
00636 };
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines