A single threaded or a multi threaded application may have a thread block on a system call, thereby delaying the update. This is particularly problematic for multi-threaded applications since one thread blocking on a system call may indefinitely delay the update of the code of another thread. That's because all threads need to be blocked by our system to update and we cannot tell how long a thread will block on a system call. Examples include waiting to read user input, waiting to receive data from a network socket, or writing to a file on disk. This indefinite blocking possibility exists because the thread waits to acquire a lock, or is put to sleep on a queue inside the operating system kernel. We aim to provide an updating solution that does not rely on the operating system and as such refrain from instrumenting lock acquisition and release inside the kernel.
We automatically transform applications to always issue I/O as a non-blocking operation that allows the runtime system to regain control over execution. Blocking system calls that are handled include accept(), read(), recv() and select(). Blocking calls not yet handled include pselect(), recvfrom(), and recvmsg().
We automatically segment the sendfile() operation to smaller chunks to ensure the system call won't block indefinitely. The write(), send(), and operations are not broken to smaller chunks yet.
![]() | Since there are some blocking system calls that the compiler does not handle yet, the compiler will stop with an error if it encounters such blocking system calls. This behavior can be overriden by supplying the argument --ignore-unsupported-blocking-system-calls. Disabling this safeguard opens the possibility for a program to block indefinitely if an update is requested and the program executes a blocking system call that does not return. |