title: CHIP8 in C - How to correctly handle the delay timer?
body: <p><strong>TL;DR</strong> I need to emulate a timer in C that allows concurrent writes and reads, whilst preserving constant decrements at 60 Hz (not exactly, but approximately accurate). It will be part of a Linux CHIP8 emulator. Using a thread-based approach with shared memory and semaphores raises some accuracy problems, as well as race conditions depending on how the main thread uses the timer.</p>
  
  <p><em>Which is the best way to devise and implement such a timer?</em></p>
  
  <hr>
  
  <p>I am writing a Linux CHIP8 interpreter in C, module by module, in order to dive into the world of emulation.</p>
  
  <p>I want my implementation to be as accurate as possible with the specifications. In that matter, timers have proven to be the most difficult modules for me.</p>
  
  <p>Take for instance the delay timer. In the specifications, it is a "special" register, initally set at 0. There are specific opcodes that set a value to, and get it from the register.</p>
  
  <p>If a value different from zero is entered into the register, it will automatically start decrementing itself, at a frequency of 60 Hz, stopping once zero is reached.</p>
  
  <p>My idea regarding its implementation consists of the following:</p>
  
  <ol>
  <li><p>The use of an ancillary thread that does the decrementing automatically, at a frequency of nearly 60 Hz by using <code>nanosleep()</code>. I use <code>fork()</code> to create the thread for the time being.</p></li>
  <li><p>The use of shared memory via <code>mmap()</code> in order to allocate the timer register and store its value on it. This approach allows both the ancillary and the main thread to read from and write to the register.</p></li>
  <li><p>The use of a semaphore to synchronise the access for both threads. I use <code>sem_open()</code> to create it, and <code>sem_wait()</code> and <code>sem_post()</code> to lock and unlock the shared resource, respectively.</p></li>
  </ol>
  
  <p>The following code snippet illustrates the concept:</p>
  
  <pre><code>void *p = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
  /* Error checking here */
  
  sem_t *mutex = sem_open("timersem", O_CREAT, O_RDWR, 1);
  /* Error checking and unlinking */
  
  int *val = (int *) p;
  *val = 120; // 2-second delay
  
  pid_t pid = fork();
  
  if (pid == 0) {
      // Child process
      while (*val &gt; 0) { // Possible race condition
          sem_wait(mutex); // Possible loss of frequency depending on main thread code
          --(*val); // Safe access
          sem_post(mutex);
          /* Here it goes the nanosleep() */
      }
  } else if (pid &gt; 0) {
      // Parent process
      if (*val == 10) { // Possible race condition
          sem_wait(mutex);
          *val = 50; // Safe access
          sem_post(mutex);
      }
  }
  </code></pre>
  
  <p>A potential problem I see with such implementation relies on the third point. If a program happens to <em>update</em> the timer register once it has reached a value <em>different from zero</em>, then the ancillary thread <strong>must not</strong> wait for the main thread to unlock the resource, or else the 60 Hz delay will not be fulfilled. This implies both threads may freely update and/or read the register (constant writes in the case of the ancillary thread), which obviously introduces race conditions.</p>
  
  <p>Once I have explained what I am doing and what I try to achieve, my question is this:</p>
  
  <p><em>Which is the best way to devise and emulate a timer that allows concurrent writes and reads, whilst preserving an acceptable fixed frequency?</em></p>