What was missing?
open()
read()
/write()
read()
num
- partial readwrite()
num
- partial writeclose()
lseek()
What happens if the offset is bigger than the file size?
demo/file-interface/sparse-file.c
ftruncate()
ftruncate()
demodemo/file-interface/truncate.c
demo/file-interface/py-file-ops.py
demo/file-interface/c-file-ops.c
dup()
open()
vs dup()
demodemo/file-interface/open-vs-dup.c
demo/file-interface/close-stdout.c
stdout
and calling dup?dup2()
How does the OS operate them?
Char Devices | Block Devices |
---|---|
read/write one byte | read/write blocks of data |
slow |
| fast |
| no seek | seek | | no buffering | buffering |
Linux abstracts an I/O device as a special file
/dev
student@OS:~$ ls -l /dev/
crw-rw-rw- 1 root root 1, 3 nov 6 20:31 null
crw-rw-rw- 1 root root 1, 8 nov 6 20:31 random
brw-rw---- 1 root disk 8, 1 nov 6 20:31 sda1
brw-rw---- 1 root disk 8, 2 nov 6 20:31 sda2
brw-rw---- 1 root disk 8, 5 nov 6 20:31 sda5
brw-rw---- 1 root disk 8, 6 nov 6 20:31 sda6
crw-rw-rw- 1 root tty 5, 0 nov 6 20:31 tty
crw-rw-rw- 1 root root 1, 9 nov 6 20:31 urandom
crw-rw----+ 1 root video 81, 0 nov 6 20:31 video0
crw-rw----+ 1 root video 81, 1 nov 6 20:31 video1
crw-rw-rw- 1 root root 1, 5 nov 6 20:31 zero
...
demo/devices/read-from-device.sh
student@OS:~$ cat /dev/input/mouse1
If not friend, why friend shaped?
ioctl()
- I/O Controlioctl()
demodemo/devices/hwaddr-ioctl.c
demo/devices/filesystem-size.c
/dev
have a corresponding physical device/dev/zero
, /dev/null
read()
from /dev/null
static ssize_t read_null(struct file *file, char __user *buf,
size_t count, loff_t *ppos) {
return 0;
}
write()
to /dev/null
static ssize_t write_null(struct file *file,
const char __user *buf, size_t count, loff_t *ppos) {
return count;
}
read()
from /dev/zero
(simplified)static ssize_t read_zero(struct file *file, char __user *buf,
size_t count, loff_t *ppos) {
size_t cleared = 0;
while (count) {
size_t chunk = min_t(size_t, count, PAGE_SIZE);
size_t left = clear_user(buf + cleared, chunk);
cleared += chunk;
count -= chunk;
}
return cleared;
}
write()
to /dev/zero
static ssize_t write_zero(struct file *file,
const char __user *buf, size_t count, loff_t *ppos) {
return count;
}
pipe()
demodemo/IPC/pipe.c
student@os:~$ ls -l my_fifo
prw-r--r-- 1 student student 0 nov 22 18:38 my_fifo
mkfifo()
demodemo/IPC/fifo.c
stream
, datagram
socket()
read()
/write()
operationsfseek
AF_UNIX
for communication on the same hostAF_INET
for communication over the internetsocket()
bind()
listen()
accept()
socket()
connect()
send()
/recv()
read()
/write()
send()
send()
failednum
- partial send()
recv()
recv()
failednum
- partial recv()
bound
to the fileconnects
to the server using the filestudent@os:~/.../demo/IPC$ ls -l
srwxrwxr-x 1 student student 0 dec 2 16:03 unix_socket
demo/IPC/unix_socket_server.c
demo/IPC/unix_socket_client.c
217.182.27.243:25565
demo/IPC/stream_socket_server.c
demo/IPC/stream_socket_client.c
demo/IPC/datagram_socket_server.c
demo/IPC/datagram_socket_client.c
libc
Bufferingstdout
vs stderr
demo/optimizations/stdout-vs-stderr.c
student@os:~/.../demo/optimizations$ ./stdout-vs-stderr
Join the dark side!
Hello from the other side!
strace --trace=write ./stdout-vs-stderr
stderr
results in a write()
stdout
result in one single write()
stdout
is buffered to avoid multiple context switchesstderr
as we want to see errors as they occurdemo/optimizations/fwrite-10000.c
demo/optimizations/write-10000.c
libc
buffering reduces the number of context switcheswrite()
is a major bottlenecklibc
write()
fills a buffer in kernel spacefsynk()
is calledwrite()
student@os:~$ cat /proc/sys/vm/dirty_expire_centisecs
3000
demo/optimizations/write-10000.c
demo/optimizations/write-1000-unbuf.c
zero-copy
sendfile()
instructs kernel to copy data from one of its buffers to anotherread()
operation resumesread()
blocksO_NONBLOCK
makes operations return rather than blockSOCK_NONBLOCK
for socketsepoll
Interfaceepoll_create()
epoll_ctl()
epoll_wait()
epoll_create()
epoll_ctl()
epoll_ctl()
epoll_ctl()
epoll_ctl()
epoll_ctl()
epoll_ctl()
epoll_wait()
demo/optimizations/client.py
for the client implementationdemo/optimizations/client_bench.sh
to compare implementationsdemo/optimizations/server.py
demo/optimizations/mp_server.py
demo/optimizations/mt_server.py
demo/optimizations/async_server.py
epoll
instance