Edit

kc3-lang/kc3/libkc3/rusage.c

Branch :

  • libkc3/rusage.c
  • #include <stdio.h>
    
    #if ! (defined(WIN32) || defined(WIN64))
    # include <fcntl.h>
    # include <sys/resource.h>
    # include <unistd.h>
    #endif
    
    #if defined(__OpenBSD__)
    # include <sys/sysctl.h>
    #endif
    
    #include "rusage.h"
    
    #if ! (defined(WIN32) || defined(WIN64))
    static bool rusage_get (struct rusage *usage)
    {
      return getrusage(RUSAGE_SELF, usage) == 0;
    }
    #endif
    
    static bool rusage_memory (u64 *rss_bytes, u64 *virtual_bytes)
    {
    #if defined(__OpenBSD__)
      struct kinfo_proc process;
      size_t size;
      int mib[6];
      mib[0] = CTL_KERN;
      mib[1] = KERN_PROC;
      mib[2] = KERN_PROC_PID;
      mib[3] = getpid();
      mib[4] = sizeof(process);
      mib[5] = 1;
      size = sizeof(process);
      if (sysctl(mib, 6, &process, &size, NULL, 0) == -1)
        return false;
      *rss_bytes = (u64) process.p_vm_rssize * (u64) getpagesize();
      *virtual_bytes = ((u64) process.p_vm_tsize +
                        (u64) process.p_vm_dsize +
                        (u64) process.p_vm_ssize) * (u64) getpagesize();
      return true;
    #elif defined(__linux__)
      FILE *f;
      unsigned long long resident_pages;
      unsigned long long virtual_pages;
      long page_size;
      if (! (f = fopen("/proc/self/statm", "r")))
        return false;
      if (fscanf(f, "%llu %llu", &virtual_pages, &resident_pages) != 2) {
        fclose(f);
        return false;
      }
      fclose(f);
      if ((page_size = sysconf(_SC_PAGESIZE)) <= 0)
        return false;
      *rss_bytes = (u64) resident_pages * (u64) page_size;
      *virtual_bytes = (u64) virtual_pages * (u64) page_size;
      return true;
    #else
      (void) rss_bytes;
      (void) virtual_bytes;
      return false;
    #endif
    }
    
    u64 * rusage_current_rss_bytes (u64 *dest)
    {
      u64 virtual_bytes;
      if (! rusage_memory(dest, &virtual_bytes))
        return NULL;
      return dest;
    }
    
    u64 * rusage_max_rss_bytes (u64 *dest)
    {
    #if ! (defined(WIN32) || defined(WIN64))
      struct rusage usage;
      if (! rusage_get(&usage))
        return NULL;
    # if defined(__APPLE__)
      *dest = usage.ru_maxrss;
    # else
      *dest = (u64) usage.ru_maxrss * 1024;
    # endif
      return dest;
    #else
      (void) dest;
      return NULL;
    #endif
    }
    
    u64 * rusage_open_files (u64 *dest)
    {
    #if defined(__OpenBSD__)
      *dest = getdtablecount();
      return dest;
    #elif ! (defined(WIN32) || defined(WIN64))
      int fd;
      int size;
      u64 count;
      count = 0;
      size = getdtablesize();
      fd = 0;
      while (fd < size) {
        if (fcntl(fd, F_GETFD) != -1)
          count++;
        fd++;
      }
      *dest = count;
      return dest;
    #else
      (void) dest;
      return NULL;
    #endif
    }
    
    s_time * rusage_system_cpu_time (s_time *dest)
    {
    #if ! (defined(WIN32) || defined(WIN64))
      struct rusage usage;
      if (! rusage_get(&usage))
        return NULL;
      *dest = (s_time) {
        .tv_sec = usage.ru_stime.tv_sec,
        .tv_nsec = usage.ru_stime.tv_usec * 1000
      };
      return dest;
    #else
      (void) dest;
      return NULL;
    #endif
    }
    
    s_time * rusage_user_cpu_time (s_time *dest)
    {
    #if ! (defined(WIN32) || defined(WIN64))
      struct rusage usage;
      if (! rusage_get(&usage))
        return NULL;
      *dest = (s_time) {
        .tv_sec = usage.ru_utime.tv_sec,
        .tv_nsec = usage.ru_utime.tv_usec * 1000
      };
      return dest;
    #else
      (void) dest;
      return NULL;
    #endif
    }
    
    u64 * rusage_virtual_bytes (u64 *dest)
    {
      u64 rss_bytes;
      if (! rusage_memory(&rss_bytes, dest))
        return NULL;
      return dest;
    }