Resource Allocation
- deadlocks
- distinguishable vs. interchangeable resources
- input is a sequence of requests for resources
- output is a sequence of granting of or denial of resources
- resource management is state-dependent: what may not work today
might work tomorrow
- scheduler can be thought of as a resource manager for CPU time
- garbage collection
Deadlock
- before using a resource, lock it
- what if using more than one resource?
- I lock resource A
- other process/thread locks resource B
- I try to lock resource A
- other process/thread tries to lock resource B
- deadlocks are caused by loops in resource locking
Distinguishable Resources
- examples
- disks
- files
- time in a real-time system
- terminals and pseudo-terminals
- pipes
- network interfaces
- friends
- can use locks instead of semaphores
- identity is important
Interchangeable Resources
- examples
- memory space
- disk space
- time in a non-real-time system
- network bandwidth
- file descriptors
- process/thread identifiers
- cash
- can use semaphores instead of locks
- capacity (not identity) is important
Resource Allocation:
Greedy Algorithm
- when a process asks for a resource:
- grant it if possible
- fail (or kill process) otherwise
- example: void * malloc(sizet size);
- returns 0 (NULL) if no memory is available
- if a higher priority process wants a resource held by a lower-priority
process, can:
- fail request
- give lower-priority thread temporary higher priority
- kill process (maybe done by super-user)
- works with both distinguishable and interchangeable resources
Resource Allocation: Quotas
- "reservations" (e.g. at a restaurant)
- quota command on Unix displays your disk quota
- limit command on Unix displays (for esb):
cputime | unlimited |
filesize | unlimited |
datasize | 2097148 kbytes |
stacksize | 8192 kbytes |
coredumpsize | 0 kbytes |
vmemoryuse | unlimited |
descriptors | 64 |
|
Resource Allocation: Quotas
- example: bandwidth reservation on networks
- quotas only work with interchangeable resources
- quotas work best with abundant resources:
- statistical multiplexing lets people think they can have more
than the system provides
- example: telephone system (if everyone called at once, system would fail)
Reliability
- state-dependent system, e.g. available today not tomorrow
- some languages want to make guarantees about what programs
will and will not work ( safe languages, e.g. Java)
- the only way you can tell if a resource request will work is
by looking at the entire system
- How can you tell if your resource management system is working?
- must look at entire state
- test using small, "artificial" state
- if suspect bugs, try to reconstruct system state at time of
allocation failure, maybe by keeping logs
Leaks
- when do you release a resource?
- too early: program will malfunction (e.g. use the same area of
memory for two different purposes)
- too late: program will consume more resources than necessary
- not at all: program will "leak" the resource (especially
long-running programs)
- memory leaks: errors, or lack of clarity about which part of the
program is responsible for deallocating a specific piece of memory
- zombie or unused processes/threads
Garbage Collection
- when a process terminates, all its resources can be reclaimed
- if we can identify the resources used by a process, we can free
the ones that are not used
- example: memory
- a safe program (one that does not dynamically compute pointers)
will only access memory locations identified by pointers in:
- registers (roots)
- memory locations pointed to by the registers
- memory locations pointed to by memory locations pointed to by the registers
- ...
Garbage Collection Algorithm:
Mark and Sweep
- push the roots onto a stack
- while the stack is not empty:
- pop the top element e off the stack
- if *e is marked, go back to previous step, otherwise:
- mark *e
- get length l of e[]
- push onto the stack each pointer in e[0... l-1]
- loop through all resources, and collect (free) those that
are not marked