I have been mucking around with low-level system programming recently. I must admit, for someone who has a little C knowledge and is used to the glossy GUI of Windows, UNIX and System programming can be…messy to say the least.
Interestingly, most system calls have the following format
void sys_call (int * ret_val)
int sys_call ( )
Because of this, programmers have to declare a variable for storing the return value from a system call rather than use it directly in computations. This seems counter-intuitive and didn’t really make sense to me for a long time. I checked in many places on the Internet hoping I could understand why this paradigm was chosen but in vain.
Finally, I believe I have solved it!
This paradigm has to do with the user space and kernel space concept of the kernel. System calls provide the interface between these two spaces. The idea is that the kernel will have all permissions to access, modify, create and delete files and data in memory. Whereas, the users have limited permissions.
When you use the
void sys_call (int * ret_val) way to use syscalls, You are effectively asking the kernel to do something and put the return value in the memory address (pointer) passed to it by the program. Since the kernel has the access to all the memory addresses, this has no problem.
However, when you use the
int sys_call ( ) way. You are asking the kernel to do the computation, allocate a memory address to store the value and then send back the value.
It’s important to understand that UNIX comes from a time when memory was precious and I/O was terribly, terribly slow. Hence they would try to make it as efficient as possible.
The return int way of doing sys_calls has the overhead of actually allocating a memory in location;copying the data onto this memory location and when returning from the method, copying it onto the left hand side of the expression.
Whereas in the void way, you just have to copy the data onto the memory location. Since RAM was constant time lookup, this took the same time irrespective of the memory address, be it kernel or user space.
That was pretty cool trick to optimize for a problem long forgotten.