Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:49:45

0001 #pragma once
0002 /**
0003 sproc.h
0004 ===========
0005 
0006 Implementations of VirtualMemoryUsageMB of a process.
0007 Migrated from former SProc.hh.  
0008 
0009 Survey usage, mostly ExecutableName::
0010 
0011     epsilon:opticks blyth$ opticks-fl sproc.h
0012     ./CSGOptiX/CSGOptiX.cc    ## ExecutableName
0013     ./CSG/CSGFoundry.cc       ## NOT USED : REMOVED
0014     ./sysrap/sproc.h
0015     ./sysrap/spath.h          ## spath::_ResolveToken replaces $ExecutableName  
0016 
0017 
0018     ./sysrap/SProc.hh
0019     ./sysrap/SOpticksResource.cc  ## ExecutableName 
0020 
0021     ./sysrap/CMakeLists.txt
0022     ./sysrap/tests/reallocTest.cc
0023     ./sysrap/tests/sproc_test.cc
0024 
0025     ./sysrap/SOpticks.cc       ## ExecutableName
0026 
0027     ./sysrap/SLOG.cc           ## ExecutableName
0028     ./sysrap/smeta.h           ## ExecutableName
0029     ./sysrap/SPMT.h            ## ExecutableName 
0030     ./sysrap/SGeo.cc           ## NOT USED : COMMENTED
0031     ./qudarap/QPMT.hh          ## ExecutableName
0032 
0033     epsilon:opticks blyth$ 
0034 
0035 
0036 **/
0037 
0038 #include <cstddef>
0039 #include <cassert>
0040 #include <iostream>
0041 #include <cstring>
0042 #include <cstdlib>
0043 
0044 
0045 
0046 struct sproc 
0047 {
0048     static constexpr const int32_t K = 1000 ;   // 1024?
0049     static int32_t parseLine(char* line); 
0050 
0051     static int Query(int32_t& virtual_size_kb, int32_t& resident_size_kb ); 
0052 
0053     static float VirtualMemoryUsageMB();
0054     static float VirtualMemoryUsageKB();
0055     static float ResidentSetSizeMB();
0056     static float ResidentSetSizeKB();
0057 
0058     static char* ExecutablePath(bool basename=false); 
0059     static char* _ExecutableName(); 
0060     static bool StartsWith( const char* s, const char* q); 
0061     static char* ExecutableName(); 
0062 };
0063 
0064 
0065 
0066 /**
0067 sproc::parseLine
0068 -----------------
0069 
0070 Expects a line of the below form with digits and ending in " Kb"::
0071 
0072    VmSize:    108092 kB
0073 
0074 **/
0075 
0076 inline int32_t sproc::parseLine(char* line){
0077     int i = strlen(line);
0078     const char* p = line;
0079     while (*p <'0' || *p > '9') p++; // advance until first digit 
0080     line[i-3] = '\0';  // chop off the " kB"
0081     return std::atoi(p);
0082 }
0083 
0084 
0085 #ifdef _MSC_VER
0086 inline void sproc::Query(int32_t& virtual_size_kb, int32_t& resident_size_kb )
0087 {
0088     virtual_size_kb = 0 ; 
0089     resident_size_kb = 0 ; 
0090 }
0091 #elif defined(__APPLE__)
0092 
0093 #include<mach/mach.h>
0094 
0095 /**
0096 https://developer.apple.com/forums/thread/105088
0097 **/
0098 
0099 inline int sproc::Query(int32_t& virtual_size_kb, int32_t& resident_size_kb )
0100 {
0101     struct mach_task_basic_info info;
0102     mach_msg_type_number_t size = MACH_TASK_BASIC_INFO_COUNT;
0103     kern_return_t kerr = task_info(mach_task_self(),
0104                                    MACH_TASK_BASIC_INFO,
0105                                    (task_info_t)&info,
0106                                    &size);
0107 
0108     int rc = 0 ; 
0109     if( kerr == KERN_SUCCESS ) 
0110     {
0111         vm_size_t virtual_ = info.virtual_size  ;  
0112         vm_size_t resident_ = info.resident_size  ;  
0113 
0114         virtual_size_kb = int32_t(virtual_/K)  ;   // narrowing 
0115         resident_size_kb = int32_t(resident_/K) ;  // narrowing 
0116     }
0117     else
0118     {
0119         rc = 1 ; 
0120         std::cerr  << mach_error_string(kerr) << std::endl   ; 
0121     }
0122     return rc ; 
0123 }
0124 
0125 
0126 #else
0127     
0128 // https://stackoverflow.com/questions/63166/how-to-determine-cpu-and-memory-consumption-from-inside-a-process
0129 
0130 inline int sproc::Query(int32_t& virtual_size, int32_t& resident_size )
0131 {
0132     FILE* file = fopen("/proc/self/status", "r");
0133     char line[128];
0134     int found = 0 ; 
0135     while (fgets(line, 128, file) != NULL){
0136         if (strncmp(line, "VmSize:", 7) == 0){
0137             virtual_size = parseLine(line);   // value in Kb 
0138             found += 1 ; 
0139             if(found == 2 ) break;
0140         } else if( strncmp(line, "VmRSS:", 6) == 0){
0141             resident_size = parseLine(line);   // value in Kb 
0142             found += 1 ; 
0143             if(found == 2 ) break;
0144         }
0145     }
0146     fclose(file);
0147     return found == 2 ? 0 : 1 ; 
0148 }
0149 
0150 
0151 #endif
0152 
0153 
0154 
0155 inline float sproc::VirtualMemoryUsageKB()
0156 {
0157     int32_t virtual_size_kb(0) ;  
0158     int32_t resident_size_kb(0) ; 
0159     Query(virtual_size_kb, resident_size_kb) ; 
0160     return virtual_size_kb ;
0161 }
0162 inline float sproc::ResidentSetSizeKB()
0163 {
0164     int32_t virtual_size_kb(0) ; 
0165     int32_t resident_size_kb(0) ; 
0166     Query(virtual_size_kb, resident_size_kb ) ; 
0167     return resident_size_kb ;
0168 }
0169 inline float sproc::VirtualMemoryUsageMB()
0170 {
0171     int32_t virtual_size_kb(0) ; 
0172     int32_t resident_size_kb(0) ; 
0173     Query(virtual_size_kb, resident_size_kb) ; 
0174     float size_mb = virtual_size_kb/K ;
0175     return size_mb  ;
0176 }
0177 inline float sproc::ResidentSetSizeMB()
0178 {
0179     int32_t virtual_size_kb(0) ; 
0180     int32_t resident_size_kb(0) ; 
0181     Query(virtual_size_kb, resident_size_kb) ; 
0182     float size_mb = resident_size_kb/K ;
0183     return size_mb  ;
0184 }
0185 
0186 
0187 
0188 
0189 /**
0190 sproc::ExecutablePath
0191 -----------------------
0192 
0193 * https://stackoverflow.com/questions/799679/programmatically-retrieving-the-absolute-path-of-an-os-x-command-line-app/1024933#1024933
0194 
0195 **/
0196 
0197 
0198 #ifdef _MSC_VER
0199 inline char* sproc::ExecutablePath(bool basename)
0200 {
0201     return nullptr ; 
0202 }
0203 #elif defined(__APPLE__)
0204 
0205 #include <mach-o/dyld.h>
0206 
0207 inline char* sproc::ExecutablePath(bool basename)
0208 {
0209     char buf[PATH_MAX];
0210     uint32_t size = sizeof(buf);
0211     bool ok = _NSGetExecutablePath(buf, &size) == 0 ; 
0212 
0213     if(!ok) std::cerr 
0214         << "_NSGetExecutablePath FAIL " 
0215         << " size " << size 
0216         << " buf " << buf 
0217         << std::endl
0218         ;
0219 
0220     assert(ok); 
0221     char* s = basename ? strrchr(buf, '/') : NULL ;  
0222     return s ? strdup(s+1) : strdup(buf) ; 
0223 }
0224 #else
0225 
0226 
0227 #include <unistd.h>
0228 #include <limits.h>
0229 
0230 inline char* sproc::ExecutablePath(bool basename)
0231 {
0232     char buf[PATH_MAX];
0233     ssize_t len = ::readlink("/proc/self/exe", buf, sizeof(buf)-1);
0234     if (len != -1) buf[len] = '\0';
0235 
0236     char* s = basename ? strrchr(buf, '/') : NULL ;  
0237     return s ? strdup(s+1) : strdup(buf) ; 
0238 }
0239 
0240 #endif
0241 
0242 
0243 inline char* sproc::_ExecutableName()
0244 {
0245     bool basename = true ; 
0246     return ExecutablePath(basename); 
0247 }
0248 
0249 
0250 inline bool sproc::StartsWith( const char* s, const char* q) 
0251 {
0252     return s && q && strlen(q) <= strlen(s) && strncmp(s, q, strlen(q)) == 0 ; 
0253 }
0254 
0255 /**
0256 sproc::ExecutableName
0257 ----------------------
0258 
0259 In embedded running with python "main" the 
0260 initial executable name is eg "python3.9".
0261 That can be overridden with envvar OPTICKS_SCRIPT 
0262 
0263 **/
0264 
0265 inline char* sproc::ExecutableName()
0266 {  
0267     char* exe0 = sproc::_ExecutableName() ; 
0268     bool is_python = sproc::StartsWith(exe0, "python") ;  
0269     char* script = getenv("OPTICKS_SCRIPT"); 
0270     char* exe = ( is_python && script ) ? script : exe0 ; 
0271     return exe ; 
0272 }
0273 
0274