I think you're missing two concepts.
- CPU privilege modes and use of
swi
are both an implementation detail of system calls
- Non-blocking system calls don't work that way
Sure, under Linux, we use swi
instructions and maintain privilege separation to implement system calls, but this doesn't reflect ARM systems in general. When you talk about Linux specifically, I think it makes more sense to refer to concepts like kernel vs user mode.
The Linux kernel have been preemptive for a long time now. If your system call is taking too long and exceeds the time quantum allocated to that process/thread, the scheduler will just kick in and do a context switch. Likewise, if your system call just consists of waiting for an event (like for I/O), it'll just get switched out until there's data available.
Taking this into account you don't usually have to worry about whether your system call takes too long. However, if you're spending a significant amount of time in a system call that's doing something that isn't waiting for some event, chances are that you're doing something in the kernel that should be done in user mode.
When the function handling the system call returns a value, it usually goes back to some sort of glue logic which restores the user context and allows the original user mode program to keep running.
Non-blocking system calls are something almost completely different. The system call handling function usually will check if it can return data at that very instant without waiting. If it can, it'll return whatever is available. It can also tell the user "I don't have any data at the moment but check back later" or "that's all, there's no more data to be read". The idea is they return basically instantly and don't block.
Finally, on your last question, I suspect you're missing the point of a system call.
You should never have to know when a task is 'completed' by a system call. If a system call doesn't return an error, you, as the process have to assume it succeeded. The rest is in the implementation details of the kernel. In the case of non-blocking system calls, they will tell you what to expect.
If you can provide an example for the last question, I may be able to explain in more detail.
SWI
is also calledSVC
. Related: Mode SVC handler starts in, Linux ARM system call, System call in ARM, Linux process context and SVC. Finally, I answer stacks, etc in ARM Linux exception stacks. – artless noisethread_info
anchored by ther13/sp
register. On a context switch, all register atomically update (to CPU) vialdm
. For the Linux kernel, theSWI
is already in supervisor mode and the code is in entry-common.S – artless noiseswi
in the user process causes an exception. During all exception, Linux saves context on the supervisor mode stack. A context switch may result in which case, the supervisor stack changes. The new supervisor stack has the new user space registers saved upon it. Also anchored in the supervisor stack is athread_info
which provides MM (memory management) info to update the MMU. This is answered in the other questions, if you read them. – artless noise