rt-watchdog 0.1.0

Real-time userspace watchdog for Rust.
Documentation
.section .text
.align 14
.globl rt_watchdog_thread_entry
rt_watchdog_thread_entry:
  // save context addr to x14
  mov x14, x0

  // start fence: wait until fence becomes 1 using futex (98)
1:
  add x0, x14, #8
  ldar w8, [x0]
  cmp w8, #1
  b.eq 2f

  // Prepare for futex syscall: FUTEX_WAIT
  add x0, x14, #8  // uaddr
  mov x1, #0      // op = FUTEX_WAIT
  mov x2, #0      // val
  mov x3, #0      // timeout (NULL)
  mov x8, #98     // syscall number for futex
  svc #0          // invoke syscall

  // Handle return values
  cmp x0, #0      // wakeup
  b.eq 1b

  cmp x0, #-11    // EAGAIN
  b.eq 1b

  cmp x0, #-4     // EINTR
  b.eq 1b

  // fail
  brk #0

2:
  // thread start ack: atomically write value 2 to fence
  mov w8, #2
  add x0, x14, #8
  stlr w8, [x0]

  // futex notify
  add x0, x14, #8  // uaddr
  mov x1, #1       // op = FUTEX_WAKE
  mov x2, #1       // val = 1 (num_waiters)
  mov x8, #98      // syscall number for futex
  svc #0           // invoke syscall

  // if return value is negative, abort process
  cmp x0, #0
  b.lt 3f

  // local counter init: 0
  eor x12, x12, x12

  // load remote counter address to x13
  add x13, x14, #0
1:
  // issue syscall sched_yield (124)
  mov x8, #124
  svc #0

  // atomically load the 64-bit remote counter
  ldar x0, [x13]

  // if x0 is equal to x12, counter did not advance - abort
  cmp x0, x12
  b.eq 3f

  // save x0 to x12
  mov x12, x0

  // loop
  b 1b

3:
  brk #0

.align 14, 0x00