9
$\begingroup$

I'm teaching an Operating System course, and was looking for an example of something that isn't a system call.

As silly as it may sound, I wasn't able to carve a good example. Everything (accessible to second-year students) that came to my mind involved system call in some way, and looking around for examples didn't help.

So, I'm reaching you: Is there any good example of operation happening on a computer that does not involve system calls?

And wish a long life to that community that I just discovered, but intend to contribute to!

Edit: the example can come from any OS, and I know that pretty much every useful program requires some system call, that's why I'm asking!

$\endgroup$
  • $\begingroup$ Doesn't that depend quite a lot on the OS? Can you be more specific? $\endgroup$ – Buffy Sep 1 '17 at 20:25
  • $\begingroup$ Pretty much any useful program effects the system in some way, whether reading/modifying a file, outputting something to the screen or otherwise. Even something like int main(){int i = 0; return 0;} has to implicitly request resources from the system to store the variable. $\endgroup$ – IllusiveBrian Sep 1 '17 at 20:30
  • 1
    $\begingroup$ Maybe an opportunity to talk about layers of abstraction in a system. The deeper you go, the more likely it is you need to talk to the kernel. $\endgroup$ – Buffy Sep 1 '17 at 20:34
  • $\begingroup$ Anyway. Welcome to CSEducators. We try to be helpful, even when we sound a bit gruff. $\endgroup$ – Buffy Sep 1 '17 at 20:36
  • 4
    $\begingroup$ The students would probably be familiar with strlen and strcmp, which are not and do not result in syscalls. Then you have printf and malloc which are not syscalls, but which may result in syscalls. $\endgroup$ – that other guy Sep 2 '17 at 2:10
13
$\begingroup$

The simple breakdown is:

  • Anything that performs input/output involes a series of system calls.
  • Anything that's purely computational doesn't involve system calls.

Both of these statements have exceptions (I/O through memory-mapped files or peripherals is I/O without syscalls, calling a hardware accelerator or allocating memory is syscalls without externally visible I/O) but they're a good approximation.

So here are some examples of operations that don't involve system calls:

  • Getting or changing the value of a variable.
  • Arithmetic operations on integers and floats.
  • Conditionals and loops whose body doesn't involve system calls.
  • Operations on strings such as searching, joining, splitting, etc.
  • Manipulations of data structures such as lists, arrays, matrices, trees, etc.
  • Memory management, as long as the program doesn't need to obtain more memory from the OS.
  • Printing to a buffered stream, if the buffer doesn't get flushed during this print call. Likewise, reading from a buffered stream, if enough bytes are available.

It would help to demonstrate by showing the system calls made by some programs, e.g. with strace on Linux, with dtruss on macOS or with Systrace under Windows. Compare a program that does a lot of I/O with one that does one big computation and prints the result.

The case of buffered I/O, suggested by ctrl+alt+delor, is an interesting one because the same library functions may or may not trigger a system call depending on the state of the system.

There is sometimes possible confusion between a library call and a system call. Unix programmers in particular tend to believe that what is documented in section 2 of the manual is system calls, but this is not true on a modern Unix systems. Every function callable from C is a C library function that's a wrapper (possibly very simple, possibly even a macro rather than a function) around a system call that usually, but not always, has the same name and takes more or less the same parameters. You can observe that on a modern Linux/x86_32 system, where many system calls have been upgraded from 32-bit arguments to 64-bit arguments, e.g. strace ls will show calls of getdents64 and fstat64 rather than getdents and fstat. Under the hood, system calls and library calls have a different calling convention. At the very least, a library call involes a jump/branch instruction while a system call involves a privilege change instruction. Depending on the system, the rules for placing arguments in registers may be different.

You can discuss how a program could make as few system calls as possible by starting from strace /bin/true. Most of its syscalls are due to dynamic linking, so write that one-line program, compile it statically and look at the remaining system calls. Reduce it even further with a more minimalistic libc such as dietlibc.

# Install dietlibc, e.g. apt-get install dietlibc-dev on Debian
$ cat a.c
int main(void) {return 0;}
$ diet gcc a.c 
$ strace ./a.out
execve("./a.out", ["./a.out"], [/* 82 vars */]) = 0
arch_prctl(ARCH_SET_FS, 0x7fff98099fe0) = 0
_exit(0)                                = ?
+++ exited with 0 +++
$\endgroup$
  • $\begingroup$ I agree +1, however memory mapped IO could result in an, implicit, system call, if there is a page fault. Where as direct IO uses explicit system calls. Also printf may not make a system call: The C library can buffer the data. The library will call flush if the buffer becomes full. You can also call flush. You will notice this sometimes, “Why does printf not work / why is output of printf delayed?”. On a gnu system (such as Gnu/Linux), as well as strace, you are free to look at the source code (though strace may be easier/quicker. $\endgroup$ – ctrl-alt-delor Sep 2 '17 at 9:27
  • 1
    $\begingroup$ @ctrl-alt-delor As I wrote: “Both of these statements have exceptions”. A page fault is not a system call. (This may be a matter of terminology, but I'll assert it, because I'm a professional OS developer and a “system call” and a “fault handler” are two separate ways to invoke kernel code, and this matches Linux and Windows terminology.) Looking at the source code doesn't tell you which system calls are executed, at most it lets you see the library calls, which as you point out are not directly related (the example of buffered IO is a nice one, thanks). $\endgroup$ – Gilles 'SO- stop being evil' Sep 2 '17 at 10:10
  • $\begingroup$ @giles [I was not disagreeing with you, just exploring these exceptions] I said implicit system call, I mean here that it triggers a service routine in the kernel. Is it correct that all access to the kernel is through interrupt service routines (hardware interrupts: page fault, device ready; and software interrupts (syscall)? $\endgroup$ – ctrl-alt-delor Sep 2 '17 at 10:33
  • 1
    $\begingroup$ @ctrl-alt-delor It's a bit dangerous to take such a general statement as absolute truth because there's usually some bizarre hardware somewhere. But for a sufficiently broad definition of “interrupt service routine” that's true. Depends if you think something like returning from hypervisor mode counts as a software interrupt. $\endgroup$ – Gilles 'SO- stop being evil' Sep 2 '17 at 10:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.