I wonder if read and write system calls on linux (used with unix sockets) do dynamic memory allocation?
The context are real time applications and deterministic behaviour.
Advertisement
Answer
No. If you look for syscalls in the Linux kernel source (I used grep -rn SYSCALL_DEFINE.*write
to find read
/write
), you can see the source for yourself:
SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) { struct fd f = fdget_pos(fd); ssize_t ret = -EBADF; if (f.file) { loff_t pos = file_pos_read(f.file); ret = vfs_read(f.file, buf, count, &pos); if (ret >= 0) file_pos_write(f.file, pos); fdput_pos(f); } return ret; } SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, size_t, count) { struct fd f = fdget_pos(fd); ssize_t ret = -EBADF; if (f.file) { loff_t pos = file_pos_read(f.file); ret = vfs_write(f.file, buf, count, &pos); if (ret >= 0) file_pos_write(f.file, pos); fdput_pos(f); } return ret; }
Note that system call definitions can be different across platforms: they don’t have to be identical for all platforms. In fact, many platforms have system calls only supported on a handful of architectures.
In your case (i.e. sockets), there is a per-socket buffer that is pre-allocated, likely via dynamic allocation. It’s easy to check what the size is for this buffer.
/proc/sys/net/ipv4/tcp_rmem (for read) /proc/sys/net/ipv4/tcp_wmem (for write)
There are also c snippets at the links above to extract those values in code.
If you try to write massive messages that exceed this buffer size, you’ll need to break them up. In general, when writing to a socket, you’ll want to create your own write()
-wrapper to confirm if all data was written, or if you need to call write()
again with a portion of the leftover data, etc.
As far as performance hits for dynamic memory allocation goes, once your socket has been created, that part is done. The greater bottleneck for throughput will be handling the I/O with the socket.