5

I am wondering if there is anything at the assembly level in x86-64 that allows you to sleep/wait, such that no instructions are run until the wait is done. I have seen the WAIT and PAUSE instructions, but I'm not sure they're related.

I would imagine it like this:

start:
  wait 123, oninterrupt ; 123 milliseconds
  ; then it will go here after that time
oninterrupt:
  ; ctrl-c pressed, now exit

Likewise, I am wondering if there are event hooks/handlers in x86. So if someone presses CTRL+C, there will be an interrupt event sent to assembly somewhere and you can run your "exit" code on that. I would imagine an event handler could be written in assembly x86 like this:

start:
  int 10, onctrlc ; register handler for made up event
  ; ... more instructions evaluate right after
onctrlc:
  ; control+c pressed, now exit

But I'm not just thinking for CTRL+C, but for any event (which I don't know that much about). I saw this tiny event loop lib in C, not sure if any of that can be done with a simple assembly instruction. Things like keyboard events, socket events, file events, other events I'm not sure what they would be.

Also, this would be run as a regular user on an operating system. But knowing how to do it for privileged users would be nice to know. And also not concerned with how you can do it with linux C functions or syscalls, I understand how to do it like that so far.

Lance
  • 75,200
  • 93
  • 289
  • 503
  • That C will compile to asm that makes system calls (via wrapper functions in libc, but you could inline them if you want). If your code is supposed to run under an OS, "sleeping" is an interaction with the process scheduler / OS, not the CPU hardware directly. \@fuz's answer is what you really want here, although \@prl's answer does correctly answer the literal question you asked based on your XY problem. – Peter Cordes Mar 22 '19 at 20:17

2 Answers2

10

The basic instruction to do what you want is HALT. It stops executing instructions until an interrupt is received.

A newer instruction that is similar is MWAIT. It waits like halt, but it also wakes up when a particular memory location is written (either by a different CPU core or by an I/O device). MWAIT also puts the CPU in a lower power state than halt does. The MONITOR instruction is used to specify the memory location that will cause MWAIT to wake up.

The other types of events you mentioned are software constructs. The CPU instructions don’t know about keyboards, files, or network devices.

MWAIT and HALT are privileged instructions. If an application wants to put the CPU to sleep, it generally needs to call the OS, so the OS can schedule some other process, if there is one ready to run.

prl
  • 11,716
  • 2
  • 13
  • 31
  • Fun fact: The WAITPKG CPU feature will add a timed-pause [`tpause`](https://www.felixcloutier.com/x86/tpause) until a given TSC count, and umonitor / [umwait](https://www.felixcloutier.com/x86/umwait) to monitor/mwait from user-space (hyperthreading-friendly alternative to spin-wait I guess, but presumably *deep* sleep like mwait isn't an option). I think these are only slated for Tremont (next-gen goldmont low-power) https://en.wikichip.org/wiki/intel/microarchitectures/tremont#New_instructions – Peter Cordes Mar 22 '19 at 20:23
3

While there are instructions to do this, they are not useful for a process running under an operating system as you are not allowed to use them. Neither do you have a way to make use of interrupts. Instead, use system calls and signals to achieve the desired goal. Useful system calls are:

  • nanosleep stops your process for the specified number of nanoseconds.
  • sigaction and signal configure what happens when a signal is received.
  • pause suspends the process until a signal is received.

On UNIX-like systems such as Linux, a SIGINT is delivered to your process when the user presses Ctrl + C. This behaviour can be used to achieve the desired result.

I recommend you to first practice all these concepts in C before diving into an assembly implementation.

fuz
  • 88,405
  • 25
  • 200
  • 352
  • I'am very surprised. You say it stops / suspends a process? The CPU has no idea about processes. I suppose you want to say it stops / suspends a thread? – Elmue Jul 11 '20 at 01:06
  • @Elmue The CPU has no idea about threads either. This question is not about threads and I do not want to complicate my answer by diving into the details of multi-threading. Note that while the methods I gave work on threads technically, it is indeed possible to susped the whole process for a given time. – fuz Jul 11 '20 at 10:00