// Copyright 2006 Google Inc. All Rights Reserved.
// Author: nsanders, menderico

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//      http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// os.cc : os and machine specific implementation
// This file includes an abstracted interface
// for linux-distro specific and HW specific
// interfaces.

#include "os.h"

#include <errno.h>
#include <fcntl.h>
#include <linux/types.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/ipc.h>
#ifdef HAVE_SHMEM
#include <sys/shm.h>
#endif
#include <unistd.h>

#ifdef HAVE_SHMEM
#ifndef SHM_HUGETLB
#define SHM_HUGETLB      04000  // remove when glibc defines it
#endif
#endif

#include <string>
#include <list>

// This file must work with autoconf on its public version,
// so these includes are correct.
#include "sattypes.h"
#include "error_diag.h"

// OsLayer initialization.
OsLayer::OsLayer() {
  testmem_ = 0;
  testmemsize_ = 0;
  totalmemsize_ = 0;
  min_hugepages_bytes_ = 0;
  normal_mem_ = true;
  use_hugepages_ = false;
  use_posix_shm_ = false;
  dynamic_mapped_shmem_ = false;
  shmid_ = 0;

  time_initialized_ = 0;

  regionsize_ = 0;
  regioncount_ = 1;
  num_cpus_ = 0;
  num_nodes_ = 0;
  num_cpus_per_node_ = 0;
  error_diagnoser_ = 0;
  err_log_callback_ = 0;
  error_injection_ = false;

  void *pvoid = 0;
  address_mode_ = sizeof(pvoid) * 8;

  has_clflush_ = false;
  has_sse2_ = false;
}

// OsLayer cleanup.
OsLayer::~OsLayer() {
  if (error_diagnoser_)
    delete error_diagnoser_;
}

// OsLayer initialization.
bool OsLayer::Initialize() {
  time_initialized_ = time(NULL);
  // Detect asm support.
  GetFeatures();

  if (num_cpus_ == 0) {
    num_nodes_ = 1;
    num_cpus_ = sysconf(_SC_NPROCESSORS_ONLN);
    num_cpus_per_node_ = num_cpus_ / num_nodes_;
  }
  logprintf(5, "Log: %d nodes, %d cpus.\n", num_nodes_, num_cpus_);
  sat_assert(CPU_SETSIZE >= num_cpus_);
  cpu_sets_.resize(num_nodes_);
  cpu_sets_valid_.resize(num_nodes_);
  // Create error diagnoser.
  error_diagnoser_ = new ErrorDiag();
  if (!error_diagnoser_->set_os(this))
    return false;
  return true;
}

// Machine type detected. Can we implement all these functions correctly?
bool OsLayer::IsSupported() {
  if (kOpenSource) {
    // There are no explicitly supported systems in open source version.
    return true;
  }

  // This is the default empty implementation.
  // SAT won't report full error information.
  return false;
}

int OsLayer::AddressMode() {
  // Detect 32/64 bit binary.
  void *pvoid = 0;
  return sizeof(pvoid) * 8;
}

// Translates user virtual to physical address.
uint64 OsLayer::VirtualToPhysical(void *vaddr) {
  // Needs platform specific implementation.
  return 0;
}

// Returns the HD device that contains this file.
string OsLayer::FindFileDevice(string filename) {
  return "hdUnknown";
}

// Returns a list of locations corresponding to HD devices.
list<string> OsLayer::FindFileDevices() {
  // No autodetection on unknown systems.
  list<string> locations;
  return locations;
}


// Get HW core features from cpuid instruction.
void OsLayer::GetFeatures() {
#if defined(STRESSAPPTEST_CPU_X86_64) || defined(STRESSAPPTEST_CPU_I686)
  // CPUID features documented at:
  // http://www.sandpile.org/ia32/cpuid.htm
  int ax, bx, cx, dx;
  __asm__ __volatile__ (
      "cpuid": "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) : "a" (1));
  has_clflush_ = (dx >> 19) & 1;
  has_sse2_ = (dx >> 26) & 1;

  logprintf(9, "Log: has clflush: %s, has sse2: %s\n",
            has_clflush_ ? "true" : "false",
            has_sse2_ ? "true" : "false");
#elif defined(STRESSAPPTEST_CPU_PPC)
  // All PPC implementations have cache flush instructions.
  has_clflush_ = true;
#elif defined(STRESSAPPTEST_CPU_ARMV7A)
#warning "Unsupported CPU type ARMV7A: unable to determine feature set."
#else
#warning "Unsupported CPU type: unable to determine feature set."
#endif
}


// We need to flush the cacheline here.
void OsLayer::Flush(void *vaddr) {
  // Use the generic flush. This function is just so we can override
  // this if we are so inclined.
  if (has_clflush_)
    FastFlush(vaddr);
}


// Run C or ASM copy as appropriate..
bool OsLayer::AdlerMemcpyWarm(uint64 *dstmem, uint64 *srcmem,
                              unsigned int size_in_bytes,
                              AdlerChecksum *checksum) {
  if (has_sse2_) {
    return AdlerMemcpyAsm(dstmem, srcmem, size_in_bytes, checksum);
  } else {
    return AdlerMemcpyWarmC(dstmem, srcmem, size_in_bytes, checksum);
  }
}


// Translate user virtual to physical address.
int OsLayer::FindDimm(uint64 addr, char *buf, int len) {
  char tmpbuf[256];
  snprintf(tmpbuf, sizeof(tmpbuf), "DIMM Unknown");
  snprintf(buf, len, "%s", tmpbuf);
  return 0;
}


// Classifies addresses according to "regions"
// This isn't really implemented meaningfully here..
int32 OsLayer::FindRegion(uint64 addr) {
  static bool warned = false;

  if (regionsize_ == 0) {
    regionsize_ = totalmemsize_ / 8;
    if (regionsize_ < 512 * kMegabyte)
      regionsize_ = 512 * kMegabyte;
    regioncount_ = totalmemsize_ / regionsize_;
    if (regioncount_ < 1) regioncount_ = 1;
  }

  int32 region_num = addr / regionsize_;
  if (region_num >= regioncount_) {
    if (!warned) {
        logprintf(0, "Log: region number %d exceeds region count %d\n",
                  region_num, regioncount_);
        warned = true;
    }
    region_num = region_num % regioncount_;
  }
  return region_num;
}

// Report which cores are associated with a given region.
cpu_set_t *OsLayer::FindCoreMask(int32 region) {
  sat_assert(region >= 0);
  region %= num_nodes_;
  if (!cpu_sets_valid_[region]) {
    CPU_ZERO(&cpu_sets_[region]);
    for (int i = 0; i < num_cpus_per_node_; ++i) {
      CPU_SET(i + region * num_cpus_per_node_, &cpu_sets_[region]);
    }
    cpu_sets_valid_[region] = true;
    logprintf(5, "Log: Region %d mask 0x%s\n",
                 region, FindCoreMaskFormat(region).c_str());
  }
  return &cpu_sets_[region];
}

// Return cores associated with a given region in hex string.
string OsLayer::FindCoreMaskFormat(int32 region) {
  cpu_set_t* mask = FindCoreMask(region);
  string format = cpuset_format(mask);
  if (format.size() < 8)
    format = string(8 - format.size(), '0') + format;
  return format;
}

// Report an error in an easily parseable way.
bool OsLayer::ErrorReport(const char *part, const char *symptom, int count) {
  time_t now = time(NULL);
  int ttf = now - time_initialized_;
  logprintf(0, "Report Error: %s : %s : %d : %ds\n", symptom, part, count, ttf);
  return true;
}

// Read the number of hugepages out of the kernel interface in proc.
int64 OsLayer::FindHugePages() {
  char buf[65] = "0";

  // This is a kernel interface to query the numebr of hugepages
  // available in the system.
  static const char *hugepages_info_file = "/proc/sys/vm/nr_hugepages";
  int hpfile = open(hugepages_info_file, O_RDONLY);

  ssize_t bytes_read = read(hpfile, buf, 64);
  close(hpfile);

  if (bytes_read <= 0) {
    logprintf(12, "Log: /proc/sys/vm/nr_hugepages "
                  "read did not provide data\n");
    return 0;
  }

  if (bytes_read == 64) {
    logprintf(0, "Process Error: /proc/sys/vm/nr_hugepages "
                 "is surprisingly large\n");
    return 0;
  }

  // Add a null termintation to be string safe.
  buf[bytes_read] = '\0';
  // Read the page count.
  int64 pages = strtoull(buf, NULL, 10);  // NOLINT

  return pages;
}

int64 OsLayer::FindFreeMemSize() {
  int64 size = 0;
  int64 minsize = 0;
  if (totalmemsize_ > 0)
    return totalmemsize_;

  int64 pages = sysconf(_SC_PHYS_PAGES);
  int64 avpages = sysconf(_SC_AVPHYS_PAGES);
  int64 pagesize = sysconf(_SC_PAGESIZE);
  int64 physsize = pages * pagesize;
  int64 avphyssize = avpages * pagesize;

  // Assume 2MB hugepages.
  int64 hugepagesize = FindHugePages() * 2 * kMegabyte;

  if ((pages == -1) || (pagesize == -1)) {
    logprintf(0, "Process Error: sysconf could not determine memory size.\n");
    return 0;
  }

  // We want to leave enough stuff for things to run.
  // If the user specified a minimum amount of memory to expect, require that.
  // Otherwise, if more than 2GB is present, leave 192M + 5% for other stuff.
  // If less than 2GB is present use 85% of what's available.
  // These are fairly arbitrary numbers that seem to work OK.
  //
  // TODO(nsanders): is there a more correct way to determine target
  // memory size?
  if (hugepagesize > 0 && min_hugepages_bytes_ > 0) {
    minsize = min_hugepages_bytes_;
  } else if (physsize < 2048LL * kMegabyte) {
    minsize = ((pages * 85) / 100) * pagesize;
  } else {
    minsize = ((pages * 95) / 100) * pagesize - (192 * kMegabyte);
  }

  // Use hugepage sizing if available.
  if (hugepagesize > 0) {
    if (hugepagesize < minsize) {
      logprintf(0, "Procedural Error: Not enough hugepages. "
                   "%lldMB available < %lldMB required.\n",
                hugepagesize / kMegabyte,
                minsize / kMegabyte);
      // Require the calculated minimum amount of memory.
      size = minsize;
    } else {
      // Require that we get all hugepages.
      size = hugepagesize;
    }
  } else {
    // Require the calculated minimum amount of memory.
    size = minsize;
  }

  logprintf(5, "Log: Total %lld MB. Free %lld MB. Hugepages %lld MB. "
               "Targeting %lld MB (%lld%%)\n",
            physsize / kMegabyte,
            avphyssize / kMegabyte,
            hugepagesize / kMegabyte,
            size / kMegabyte,
            size * 100 / physsize);

  totalmemsize_ = size;
  return size;
}

// Allocates all memory available.
int64 OsLayer::AllocateAllMem() {
  int64 length = FindFreeMemSize();
  bool retval = AllocateTestMem(length, 0);
  if (retval)
    return length;
  else
    return 0;
}

// Allocate the target memory. This may be from malloc, hugepage pool
// or other platform specific sources.
bool OsLayer::AllocateTestMem(int64 length, uint64 paddr_base) {
  // Try hugepages first.
  void *buf = 0;

  sat_assert(length >= 0);

  if (paddr_base)
    logprintf(0, "Process Error: non zero paddr_base %#llx is not supported,"
              " ignore.\n", paddr_base);

#ifdef HAVE_SHMEM
  // Determine optimal memory allocation path.
  bool prefer_hugepages = false;
  bool prefer_posix_shm = false;
  bool prefer_dynamic_mapping = false;

  // Are there enough hugepages?
  int64 hugepagesize = FindHugePages() * 2 * kMegabyte;
  // TODO(nsanders): Is there enough /dev/shm? Is there enough free memeory?
  if ((length >= 1400LL * kMegabyte) && (address_mode_ == 32)) {
    prefer_dynamic_mapping = true;
    prefer_posix_shm = true;
    logprintf(3, "Log: Prefer POSIX shared memory allocation.\n");
    logprintf(3, "Log: You may need to run "
                 "'sudo mount -o remount,size=100\% /dev/shm.'\n");
  } else if (hugepagesize >= length) {
    prefer_hugepages = true;
    logprintf(3, "Log: Prefer using hugepace allocation.\n");
  } else {
    logprintf(3, "Log: Prefer plain malloc memory allocation.\n");
  }

  // Allocate hugepage mapped memory.
  if (prefer_hugepages) {
    do { // Allow break statement.
      int shmid;
      void *shmaddr;

      if ((shmid = shmget(2, length,
              SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W)) < 0) {
        int err = errno;
        string errtxt = ErrorString(err);
        logprintf(3, "Log: failed to allocate shared hugepage "
                      "object - err %d (%s)\n",
                  err, errtxt.c_str());
        logprintf(3, "Log: sysctl -w vm.nr_hugepages=XXX allows hugepages.\n");
        break;
      }

      shmaddr = shmat(shmid, NULL, NULL);
      if (shmaddr == reinterpret_cast<void*>(-1)) {
        int err = errno;
        string errtxt = ErrorString(err);
        logprintf(0, "Log: failed to attach shared "
                     "hugepage object - err %d (%s).\n",
                  err, errtxt.c_str());
        if (shmctl(shmid, IPC_RMID, NULL) < 0) {
          int err = errno;
          string errtxt = ErrorString(err);
          logprintf(0, "Log: failed to remove shared "
                       "hugepage object - err %d (%s).\n",
                    err, errtxt.c_str());
        }
        break;
      }
      use_hugepages_ = true;
      shmid_ = shmid;
      buf = shmaddr;
      logprintf(0, "Log: Using shared hugepage object 0x%x at %p.\n",
                shmid, shmaddr);
    } while (0);
  }

  if ((!use_hugepages_) && prefer_posix_shm) {
    do {
      int shm_object;
      void *shmaddr = NULL;

      shm_object = shm_open("/stressapptest", O_CREAT | O_RDWR, S_IRWXU);
      if (shm_object < 0) {
        int err = errno;
        string errtxt = ErrorString(err);
        logprintf(3, "Log: failed to allocate shared "
                      "smallpage object - err %d (%s)\n",
                  err, errtxt.c_str());
        break;
      }

      if (0 > ftruncate(shm_object, length)) {
        int err = errno;
        string errtxt = ErrorString(err);
        logprintf(3, "Log: failed to ftruncate shared "
                      "smallpage object - err %d (%s)\n",
                  err, errtxt.c_str());
        break;
      }

      // 32 bit linux apps can only use ~1.4G of address space.
      // Use dynamic mapping for allocations larger than that.
      // Currently perf hit is ~10% for this.
      if (prefer_dynamic_mapping) {
        dynamic_mapped_shmem_ = true;
      } else {
        // Do a full mapping here otherwise.
        shmaddr = mmap64(NULL, length, PROT_READ | PROT_WRITE,
                         MAP_SHARED | MAP_NORESERVE | MAP_LOCKED | MAP_POPULATE,
                         shm_object, NULL);
        if (shmaddr == reinterpret_cast<void*>(-1)) {
          int err = errno;
          string errtxt = ErrorString(err);
          logprintf(0, "Log: failed to map shared "
                       "smallpage object - err %d (%s).\n",
                    err, errtxt.c_str());
          break;
        }
      }

      use_posix_shm_ = true;
      shmid_ = shm_object;
      buf = shmaddr;
      char location_message[256] = "";
      if (dynamic_mapped_shmem_) {
        sprintf(location_message, "mapped as needed");
      } else {
        sprintf(location_message, "at %p", shmaddr);
      }
      logprintf(0, "Log: Using posix shared memory object 0x%x %s.\n",
                shm_object, location_message);
    } while (0);
    shm_unlink("/stressapptest");
  }
#endif

  logprintf(3, "Log: Prefer plain malloc memory allocation.\n");

  if (!use_hugepages_ && !use_posix_shm_) {
    // Use memalign to ensure that blocks are aligned enough for disk direct IO.
    buf = static_cast<char*>(memalign(4096, length));
    if (buf) {
      logprintf(0, "Log: Using memaligned allocation at %p.\n", buf);
    } else {
      logprintf(0, "Process Error: memalign returned 0\n");
      if ((length >= 1499LL * kMegabyte) && (address_mode_ == 32)) {
        logprintf(0, "Log: You are trying to allocate > 1.4G on a 32 "
                     "bit process. Please setup shared memory.\n");
      }
    }
  }

  testmem_ = buf;
  if (buf) {
    testmemsize_ = length;
  } else {
    testmemsize_ = 0;
  }

  return (buf != 0);
}

// Free the test memory.
void OsLayer::FreeTestMem() {
  if (testmem_) {
#ifdef HAVE_SHMEM
    if (use_hugepages_) {
      shmdt(testmem_);
      shmctl(shmid_, IPC_RMID, NULL);
    } else if (use_posix_shm_) {
      if (!dynamic_mapped_shmem_) {
        munmap(testmem_, testmemsize_);
      }
      close(shmid_);
    } else {
      free(testmem_);
    }
#else
    free(testmem_);
#endif
    testmem_ = 0;
    testmemsize_ = 0;
  }
}


// Prepare the target memory. It may requre mapping in, or this may be a noop.
void *OsLayer::PrepareTestMem(uint64 offset, uint64 length) {
  sat_assert((offset + length) <= testmemsize_);
#ifdef HAVE_SHMEM
  if (dynamic_mapped_shmem_) {
    // TODO(nsanders): Check if we can support MAP_NONBLOCK,
    // and evaluate performance hit from not using it.
    void * mapping = mmap64(NULL, length, PROT_READ | PROT_WRITE,
                     MAP_SHARED | MAP_NORESERVE | MAP_LOCKED | MAP_POPULATE,
                     shmid_, offset);
    if (mapping == MAP_FAILED) {
      string errtxt = ErrorString(errno);
      logprintf(0, "Process Error: PrepareTestMem mmap64(%llx, %llx) failed. "
                   "error: %s.\n",
                offset, length, errtxt.c_str());
      sat_assert(0);
    }
    return mapping;
  }
#endif

  return reinterpret_cast<void*>(reinterpret_cast<char*>(testmem_) + offset);
}

// Release the test memory resources, if any.
void OsLayer::ReleaseTestMem(void *addr, uint64 offset, uint64 length) {
#ifdef HAVE_SHMEM
  if (dynamic_mapped_shmem_) {
    int retval = munmap(addr, length);
    if (retval == -1) {
      string errtxt = ErrorString(errno);
      logprintf(0, "Process Error: ReleaseTestMem munmap(%p, %llx) failed. "
                   "error: %s.\n",
                addr, length, errtxt.c_str());
      sat_assert(0);
    }
  }
#endif
}

// No error polling on unknown systems.
int OsLayer::ErrorPoll() {
  return 0;
}

// Generally, poll for errors once per second.
void OsLayer::ErrorWait() {
  sat_sleep(1);
  return;
}

// Open a PCI bus-dev-func as a file and return its file descriptor.
// Error is indicated by return value less than zero.
int OsLayer::PciOpen(int bus, int device, int function) {
  char dev_file[256];

  snprintf(dev_file, sizeof(dev_file), "/proc/bus/pci/%02x/%02x.%x",
           bus, device, function);

  int fd = open(dev_file, O_RDWR);
  if (fd == -1) {
    logprintf(0, "Process Error: Unable to open PCI bus %d, device %d, "
                 "function %d (errno %d).\n",
              bus, device, function, errno);
    return -1;
  }

  return fd;
}


// Read and write functions to access PCI config.
uint32 OsLayer::PciRead(int fd, uint32 offset, int width) {
  // Strict aliasing rules lawyers will cause data corruption
  // on cast pointers in some gccs.
  union {
    uint32 l32;
    uint16 l16;
    uint8 l8;
  } datacast;
  datacast.l32 = 0;
  uint32 size = width / 8;

  sat_assert((width == 32) || (width == 16) || (width == 8));
  sat_assert(offset <= (256 - size));

  if (lseek(fd, offset, SEEK_SET) < 0) {
    logprintf(0, "Process Error: Can't seek %x\n", offset);
    return 0;
  }
  if (read(fd, &datacast, size) != static_cast<ssize_t>(size)) {
    logprintf(0, "Process Error: Can't read %x\n", offset);
    return 0;
  }

  // Extract the data.
  switch (width) {
    case 8:
      sat_assert(&(datacast.l8) == reinterpret_cast<uint8*>(&datacast));
      return datacast.l8;
    case 16:
      sat_assert(&(datacast.l16) == reinterpret_cast<uint16*>(&datacast));
      return datacast.l16;
    case 32:
      return datacast.l32;
  }
  return 0;
}

void OsLayer::PciWrite(int fd, uint32 offset, uint32 value, int width) {
  // Strict aliasing rules lawyers will cause data corruption
  // on cast pointers in some gccs.
  union {
    uint32 l32;
    uint16 l16;
    uint8 l8;
  } datacast;
  datacast.l32 = 0;
  uint32 size = width / 8;

  sat_assert((width == 32) || (width == 16) || (width == 8));
  sat_assert(offset <= (256 - size));

  // Cram the data into the right alignment.
  switch (width) {
    case 8:
      sat_assert(&(datacast.l8) == reinterpret_cast<uint8*>(&datacast));
      datacast.l8 = value;
    case 16:
      sat_assert(&(datacast.l16) == reinterpret_cast<uint16*>(&datacast));
      datacast.l16 = value;
    case 32:
      datacast.l32 = value;
  }

  if (lseek(fd, offset, SEEK_SET) < 0) {
    logprintf(0, "Process Error: Can't seek %x\n", offset);
    return;
  }
  if (write(fd, &datacast, size) != static_cast<ssize_t>(size)) {
    logprintf(0, "Process Error: Can't write %x to %x\n", datacast.l32, offset);
    return;
  }

  return;
}



// Open dev msr.
int OsLayer::OpenMSR(uint32 core, uint32 address) {
  char buf[256];
  snprintf(buf, sizeof(buf), "/dev/cpu/%d/msr", core);
  int fd = open(buf, O_RDWR);
  if (fd < 0)
    return fd;

  uint32 pos = lseek(fd, address, SEEK_SET);
  if (pos != address) {
    close(fd);
    logprintf(5, "Log: can't seek to msr %x, cpu %d\n", address, core);
    return -1;
  }

  return fd;
}

bool OsLayer::ReadMSR(uint32 core, uint32 address, uint64 *data) {
  int fd = OpenMSR(core, address);
  if (fd < 0)
    return false;

  // Read from the msr.
  bool res = (sizeof(*data) == read(fd, data, sizeof(*data)));

  if (!res)
    logprintf(5, "Log: Failed to read msr %x core %d\n", address, core);

  close(fd);

  return res;
}

bool OsLayer::WriteMSR(uint32 core, uint32 address, uint64 *data) {
  int fd = OpenMSR(core, address);
  if (fd < 0)
    return false;

  // Write to the msr
  bool res = (sizeof(*data) == write(fd, data, sizeof(*data)));

  if (!res)
    logprintf(5, "Log: Failed to write msr %x core %d\n", address, core);

  close(fd);

  return res;
}

// Extract bits [n+len-1, n] from a 32 bit word.
// so GetBitField(0x0f00, 8, 4) == 0xf.
uint32 OsLayer::GetBitField(uint32 val, uint32 n, uint32 len) {
  return (val >> n) & ((1<<len) - 1);
}

// Generic CPU stress workload that would work on any CPU/Platform.
// Float-point array moving average calculation.
bool OsLayer::CpuStressWorkload() {
  double float_arr[100];
  double sum = 0;
  unsigned short seed = 12345;

  // Initialize array with random numbers.
  for (int i = 0; i < 100; i++) {
    float_arr[i] = nrand48(&seed);
    if (nrand48(&seed) % 2)
      float_arr[i] *= -1.0;
  }

  // Calculate moving average.
  for (int i = 0; i < 100000000; i++) {
    float_arr[i % 100] =
      (float_arr[i % 100] + float_arr[(i + 1) % 100] +
       float_arr[(i + 99) % 100]) / 3;
    sum += float_arr[i % 100];
  }

  // Artificial printf so the loops do not get optimized away.
  if (sum == 0.0)
    logprintf(12, "Log: I'm Feeling Lucky!\n");
  return true;
}

PCIDevices OsLayer::GetPCIDevices() {
  PCIDevices device_list;
  DIR *dir;
  struct dirent *buf = new struct dirent();
  struct dirent *entry;
  dir = opendir(kSysfsPath);
  if (!dir)
    logprintf(0, "Process Error: Cannot open %s", kSysfsPath);
  while (readdir_r(dir, buf, &entry) == 0 && entry) {
    PCIDevice *device;
    unsigned int dev, func;
    // ".", ".." or a special non-device perhaps.
    if (entry->d_name[0] == '.')
      continue;

    device = new PCIDevice();
    if (sscanf(entry->d_name, "%04x:%02hx:%02x.%d",
               &device->domain, &device->bus, &dev, &func) < 4) {
      logprintf(0, "Process Error: Couldn't parse %s", entry->d_name);
      free(device);
      continue;
    }
    device->dev = dev;
    device->func = func;
    device->vendor_id = PCIGetValue(entry->d_name, "vendor");
    device->device_id = PCIGetValue(entry->d_name, "device");
    PCIGetResources(entry->d_name, device);
    device_list.insert(device_list.end(), device);
  }
  closedir(dir);
  delete buf;
  return device_list;
}

int OsLayer::PCIGetValue(string name, string object) {
  int fd, len;
  char filename[256];
  char buf[256];
  snprintf(filename, sizeof(filename), "%s/%s/%s", kSysfsPath,
           name.c_str(), object.c_str());
  fd = open(filename, O_RDONLY);
  if (fd < 0)
    return 0;
  len = read(fd, buf, 256);
  close(fd);
  buf[len] = '\0';
  return strtol(buf, NULL, 0);  // NOLINT
}

int OsLayer::PCIGetResources(string name, PCIDevice *device) {
  char filename[256];
  char buf[256];
  FILE *file;
  int64 start;
  int64 end;
  int64 size;
  int i;
  snprintf(filename, sizeof(filename), "%s/%s/%s", kSysfsPath,
           name.c_str(), "resource");
  file = fopen(filename, "r");
  if (!file) {
    logprintf(0, "Process Error: impossible to find resource file for %s",
              filename);
    return errno;
  }
  for (i = 0; i < 6; i++) {
    if (!fgets(buf, 256, file))
      break;
    sscanf(buf, "%llx %llx", &start, &end);  // NOLINT
    size = 0;
    if (start)
      size = end - start + 1;
    device->base_addr[i] = start;
    device->size[i] = size;
  }
  fclose(file);
  return 0;
}
