Does every call to write sends switches to kernel mode?
Linux - KernelThis forum is for all discussion relating to the Linux kernel.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Does every call to write sends switches to kernel mode?
I know that a call to the glibc "write" function calls in it's turn to the sys_call write function which is a kernel function.
because sys_call is a kernel function the CPU has to change the ring to zero store the processes registers and so on.
But does it always switches to kernel mode? for example, if i do
write(-1,buffer,LENGTH)
does it still tries to find it in the file descriptors array?
I see in the glibc source code that it does check for fd>0 but i don't see any jump to the sys_call there (it seems like the baracks for main() ends before any call to the alias_write.
/* Write NBYTES of BUF to FD. Return the number written, or -1. */
ssize_t
__libc_write (int fd, const void *buf, size_t nbytes)
{
if (nbytes == 0)
return 0;
if (fd < 0)
{
__set_errno (EBADF);
return -1;
}
if (buf == NULL)
{
__set_errno (EINVAL);
return -1;
}
What you've found is a stub function for systems it's not implemented on. You need to look under the sysdeps tree for the actual implementation.
Note that the actual system calls aren't defined anywhere in the source tree - they're generated at build time from syscalls.list (linked is the one in sysdeps/unix, there are additional ones further down), a series of macros in sysdep.h (linked linux/i386), and a script that actually generates the source files.
–
To answer your original question, yes, a system-call ordinarily does occur. Or, depending on the architecture, something equivalent to a system call. Disk I/O in particular is a complicated process which makes heavy use of "buffering." Your process is typically allowed to continue while the actual write takes place asynchronously. (Although it can wait. sqlite often does this.)
Last edited by sundialsvcs; 02-06-2018 at 08:00 AM.
So just for the clarification,
even if i sent write(-1,0,buffer) linux will not identify the problem in user space, and will switch to kernel space?
although the glibc checks came false?
So just for the clarification,
even if i sent write(-1,0,buffer) linux will not identify the problem in user space, and will switch to kernel space?
although the glibc checks came false?
I believe you could run your program under strace and answer that yourself in just a few minutes.
I believe you could run your program under strace and answer that yourself in just a few minutes.
I'm trying to see if the libc function executed the int 0x80 (or any other form to change to kernel mode) call and changed to kernel mode.
sorry for the ignorance, but how can i do it with strace?
I'm trying to see if the libc function executed the int 0x80 (or any other form to change to kernel mode) call and changed to kernel mode.
sorry for the ignorance, but how can i do it with strace?
That's exactly what strace traces -- system calls. If you wanted to trace calls to the write(2) library function, you would use ltrace.
And why do you care ?.
Context switching takes place all the time. Literally. vmstat tells you that, but for the absolute number, try the following - repeat a couple of seconds later.
The system often spends more time in kernel mode than in user mode. (Still executing on behalf of the current process/thread.) All sorts of things require a system-call.
The x86 architecture implements call gates to provide more-direct transfers. They've since sort-of fallen out in favor of other mechanisms, but the essential notion is the same. User-land programs have frequent need to call specific subroutines (as determined solely by the OS), such that there is a perceived need to make the transition as rapid as possible.
A "system call" really is "a subroutine call," although it includes a change in the processor's privilege-level and is a one-way street: the requesting user-land program cannot make arbitrary calls into kernel space. Also, when the kernel switches back to user-land mode, it might have switched from one process/thread to another.
"This being Linux," you have all of the source-code that implements this magic on various architectures, and I suggest that it can be very, very informative and educational to "peek behind the curtain" and see what actually happens next.
Last edited by sundialsvcs; 02-07-2018 at 12:10 PM.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.