Today's Outline
- real-time scheduling: RMS, EDFS, and Linux
- file systems: API
- file system organization
- sequential file allocation
Rate Monotonic Scheduling
- only works with periodic tasks whose deadline is to complete
within the period
- assign priorities based on the period: higher priorities to
processes with shorter periods
- always run a runnable higher priority task first,
if necessary preempty a lower-priority task
- the load imposed by each process i is
timei / periodi (abbreviated
Ci / Pi)
- RMS is guaranteed to work if the total processor load is low enough,
e.g. less than 0.78 for three processes
- can guarantee hard real-time if the load is sufficiently small
Earliest Deadline First Scheduling
- non-periodic scheduling cannot use RMS
- instead, run first the process with the earliest deadline
- if there is at least one feasible schedule, then EDFS meets all
deadlines
- the processor load can be very close to 100% and EDFS will still
work (if there is at least one feasible schedule)
- EDFS does not need to be preemptive, though preemption may make
some combinations of deadlines feasible that would be infeasible
otherwise
- can guarantee hard real-time, as long as the deadlines are
reasonable and the tasks feasible
Linux Real-Time
- scheduler real-time task types:
- a SCHED_FIFO task is never pre-empted by another task
at lower priority
- a SCHED_RR task stops running at the end of its timeslice
- all real-time tasks run at higher priority (lower nice
level) than all non-real-time tasks
- real-time tasks always remain on the active queue
- soft real-time only -- no guarantees about when anything will
execute, especially if there are higher-priority tasks
- can be used to implement Rate Monotonic Scheduling,
by assigning different priorities to different tasks
- real-time tasks could lock up a sytem if they fail to yield,
suspend, or sleep
File System Overview
- files are collections of data:
- ordered collection of bytes
- ordered collection of fixed-size records
- collection of fixed-size records accessed by keys
- each file has a name
- files are usually placed in a tree (or DAG) directory structure
- each directory also has a name
- internally, each directory may be implemented as a special file whose
contents are records, each indicating a file or subdirectory
- the file system API must support reading and writing (and executing)
files
- the file system API must support accessing directories by looking up
files (and sub-directories), creating files, renaming files,
and deleting files
File System Usage
- the complete path or pathname for a file
includes the names of all directories from the root to that file,
with a system-dependent directory separator
- unix example: /a/b/c/d
- dos/windows example: \a\b\c\d
- multics example: >a>b>c>d
- the above are absolute file names. A relative file
name can be turned into an absolute file name by preceding it with the
absolute path of the current directory
- example: if the current directory is /a/b/c,
file name d refers to /a/b/c/d, and so on
Unix File System API: accessing files
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
int creat(const char *pathname, mode_t mode);
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
off_t lseek(int fildes, off_t offset, int whence);
int fstat(int filedes, struct stat *buf);
int close(int fd);
- open and creat return a file descriptor (fd), a small integer
representing the open file (or -1 in case of error)
- everything else has fd as its first argument -- in an object-oriented
language, could have an object with
read, write, seek, fstat, and
close methods.
- reading requests a number of bytes which should be less than or
equal to the size of the buffer, returns the number of bytes read
- writing writes the requested number of bytes, returns the
number of bytes written (usually same as requested or -1 for errors)
- reading and writing both advance the position, seek sets it explicitly
- stat returns information about the file
directory structure
- a directory can be stored as a regular file with some special
attributes
- each record in the directory file stores information about one
sub-file or sub-directory: at least the name, and a pointer to
information about the file itself (the inode in unix, or a
list of blocks containing the file contents)
- the records may be fixed length or variable length
- many older operating systems use fixed length records, and so
put stringent limits on file name length to save space
- newer operating systems allow long (but usually not unlimited)
file name lengths, and use variable sized records
File System API: accessing directories
int rename(const char *oldpath, const char *newpath);
int link(const char *oldpath, const char *newpath);
int symlink(const char *oldpath, const char *newpath);
int unlink(const char *pathname);
DIR *opendir(const char *name);
struct dirent *readdir(DIR *dir);
int closedir(DIR *dir);
int scandir(const char *dir, struct dirent ***namelist,
int (*select)(const struct dirent *),
int (*compar)(const void *, const void *));
- renaming a file is done by the operating system, as is any
writing of the file containing the directory entries
- Unix permits any number of directory entries (i.e. any number
of names) to point to the same inode (same file) -- in Unix,
this is a hard link
- when the last (hard) link is removed, only then is the file deleted
- for example, an open file may have been unlinked, but is still
in use, so is not deleted even though it is not accessible through
the directory tree
- a soft link is a short file containing the name of the file that is
being linked to -- if the underlying file is renamed or deleted, the soft
link becomes invalid (but is still in the file system)
- stat returns information about a file, e.g. creation time, size, etc
- opendir, readdir, and closedir are used to loop through the entries
in a directory
- scandir loops through the entries of a directory, selects some,
and sorts the result, returning a list (array) of file names
File System Organization
- the file system is stored on disk or on some other non-volatile
medium, e.g. flash
- when the machine boots, the disk must provide (a) the boot program,
and also (b) the information to rebuild the internal file system structures
- (a) is stored in the boot block, (b) in the superblock
- the superblock must store basic disk usage information (e.g. block
size), information about which blocks are not allocated (free list),
and at least a pointer to the root directory
Sequential File Storage
- in a sequential file allocation system, each file is a contiguous
group of blocks
- fast sequential access does not require seeking
- allocation is hard: must know size of file before you can create it
- must also find for a big enough gap between other files -- the space
may be available, but if it is not contiguous, it is no good
- can periodically defragment by copying all existing
files so they are all at one end of the disk
- useful where there is no deletion, i.e. in write-once file systems,
e.g. on CD-Rs