Today: VM wrap-up Select (if time) Course wrap-up Final Evaluations
Program structure int A[1024][1024] ; Each row is stored in one page Ignore code page in this example One frame allocated Program 1 for (j = 0; j< 1024; j++) for (i = 0; i< 1024;i++) A[i][j] = i*j; 1024 x 1024 page faults 2
Program 2 for (i = 0; i< 1024; i++) for (j = 0; j< 1024;j++) A[i][j] = i*j; 1024 page faults 3
Asynchrony Many programs need to establish multiple I/O channels Need concurrent channels e.g. webserver requests and replies http files and images Challenge: don t know which channels are ready We ve seen many ways to handle this
One way Threads Use a separate thread to handle each I/O channel Each thread manages channel with standard blocking calls read and write Potential Issues? threads must be able to block safely threads consume resources Lab #4
Other options Polling-based (lab #2) use non-blocking I/O on read/write retry if nothing there Problems with this solution: lots of system calls! complexity performance how often to retry?
Other options (cont d) Set up signal handlers to deal with I/O completion events (SIGIO) For some I/O devices, you can set O_NONBLOCK O_ASYNC and get sent a signal when input or output is ready the appeal? works for network sockets Setup SIGIO handler Get an fd corresponding to network connection Use fcntl to set properties on this fd fd = accept (.); Emulated this in lab #3 fcntl (fd, F_SETFL, O_NONBLOCK O_ASYNC);
Approach is limited Using I/O signals limited to certain channel types works for a single channel any multiplexing has to be layered on top multiple channels: which channel caused the signal?
Another option: Select More efficient polling and multiplexing Use select() to wait for multiple I/O channels simultaneously select generally requires fewer system calls blocks if NOTHING is ready
#include <sys/select.h> I/O multiplexing int select (int n, fd_set *readfds, NULL, NULL, struct timeval *timeout); n is the max fd # to check (max_fd + 1) readfds contain fds of interest; can be NULL, if don t care timeval is the timeout how long to wait, NULL if forever returns -1 on failure modifies fd_set to indicate those that are ready
Using select (cont d) Write your program as an event-loop Before each call to select, set the fd set to be monitored fds as select will clear bits not ready when it returns Set n appropriately (max(fd)+1) Call select to see what is ready Act on the ready fd (i.e. do the I/O) Repeat
Init and set fd bits: Using select (cont d) FD_ZERO (fd_set *set); // init a set FD_SET (int fd, fd_set *set); // set this fd for monitoring FD_CLR (int fd, fd_set *set); // clear a bit FD_ISSET (int fd, fd_set *set); // is fd in the ready set?
Using select Example: want to read from multiple sources while (1) { // set/restore monitored fd_set each time through the loop FD_ZERO (&readset); FD_SET (fd1, &readset); FD_SET (fd2, &readset); max_fd = max (fd1, fd2); select (max_fd+1, &readset, NULL, NULL, NULL); if (FD_ISSET (fd1, &readset) read (fd1,.); if (FD_ISSET (fd2, &readset) read (fd2,.); }
Using select (cont d) Select blocks until >=1 fd is ready Returns a value > 0 Select returns due to timeout Returns a value = 0 Select returns a value < 0 if an error in select call
Lab #2 without non-blocking reads! fd_set rfds; FD_ZERO(&rfds); for (i=0; i<total_tabs; i++) { if(channel[i].child_to_parent_fd[0]!=0) FD_SET(channel[i].child_to_parent_fd[0], &rfds); if(channel[i].child_to_parent_fd[0] > max_fd) max_fd = channel[i].child_to_parent_fd[0]; } select(max_fd + 1, &rfds, NULL, NULL, NULL); for(i=0; i<total_tabs; i++){ if(fd_isset(channel[i].child_to_parent_fd[0], &rfds)){ //Child 'i' has sent a request
Course wrap-up tell me about 4061 Systems are complex beasts Programming them is hard - concurrency - asynchrony - multiple interacting components - metrics (sometimes competing): performance, reliability, security - stakeholders: user, admin, system
Abstraction hides complexity promotes usability Systems programming abstractions Process: running program/resource container I/O: data movement to/from external device File: container for data Directory: container for related files Pipes/Mailbox: communication stream Thread: control Synchronization: CV, semaphore, lock Socket: communication end-point
Want more? Take CSCi 5103 Operating Systems
The Final: Closed: I ll give APIs 90% incremental since exam #2 semaphores, CVs, ME, BB, RW, barriers network programming: sockets, addressing, etc. virtual memory 10% older Length of an in-class exam ~ 35% short answer ~ 65% longer answer
3 Longer questions (programming/analysis): Virtual memory Network programming Synchronization Will post a sample exam