CSE 451: Introduction to
Operating Systems
Section 2, April/5/2001
Jochen
Jäger
1.
Solutions to Unix
tasks
2.
Project turn in
procedure/policy
3.
Questions about lecture,
project, etc
4.
Scheduler, processes &
context switching
Basic Unix commands:
pwd:
print name of current/working directory
cd:
Change working directory (cd returns to homedir)
ls:
list directory contents
find:
search for files in a directory hierarchy
grep:
print lines matching a pattern
more:
file viewer, see also less
cat:
print files on stdout, see also: cat file1 >>
file2
cp:
copy files and directories
man:
format and display the on-line manual pages
vi:
text editor
emacs:
text editor, see also xemacs
Tasks:
find a file called sched.h
ls
sched.h
find a textstring in
sched.h
grep define
sched.h
find a textstring in all .h
and .c files in the current directory
grep define
*.[ch]
find a textstring in all .h
and .c files in all subsequent dirs
grep define `find . -name '*.[ch]'`
Attention this is not the
same:
find . -name '*.[ch]' | grep
define
find all files recently
modified
ls -rt
find last 5 most recently
files
ls –rt | tail -5
find all files modified
within the last 48 hours
find . –ctime 2
Project
turn-in:
Accepted formats:
-
Email: Plain Text, Word, PS,
PDF
-
Hardcopy: name, project nr,
date on cover sheet and paper clipped or stapled at left top corner
or name, project nr, date on
every sheet
Turn-in time (both
electronically as well as hardcopy):
end
of sections
Late Policy:
we
will take off 20% for each day (or portion thereof) it is
late.
The
Gilligan's Island Rule:
-
that you are free to meet
with fellow students(s) and discuss assignments with them.
-
Writing on a board or shared
piece of paper is acceptable during the meeting; however, you should not take
any written (electronic or otherwise) record away from the
meeting.
-
This applies when the
assignment is supposed to be an individual effort or whenever two teams discuss
common problems they are each encountering (inter-group collaboration).
-
After the meeting, engage in
a half hour of mind-numbing activity (like watching an episode of Gilligan's
Island), before starting to work on the assignment. This will assure that you
are able to reconstruct what you learned from the meeting, by yourself, using
your own brain.
The
Freedom of Information Rule:
To
assure that all collaboration is on the level, you must always write the name(s)
of your collaborators on your assignment.
Scheduler selects process
which will run next
Linux uses pre-emptive
scheduling
Time-slice: e.g.
200ms
Quantum: time for a process
during one epoch
Epoch: CPU scheduling
cycle
The
epoch ends when all runnable processes have exhausted their quantum; in this
case, the scheduler algorithm recomputes the time-quantum durations of all
processes and a new epoch begins.
struct task_struct
{
…
long
counter; // amount of time (in jiffies) that this process is allowed to run for,
it is decremented each clock tick.
long
nice;
unsigned long policy; //
scheduling policy for this process: normal or real time (round robin or first in
first out)
struct mm_struct *mm;
int
has_cpu, processor;
unsigned long cpus_allowed;
…
struct task_struct *next_task, *prev_task;
struct mm_struct
*active_mm;
…
pid_t pid;
pid_t pgrp;
…
unsigned long rt_priority;
…
uid_t uid,euid,suid,fsuid;
gid_t gid,egid,sgid,fsgid;
...
struct user_struct *user;
…
};
The
schedule( ) Function
Direct invocation: when the
current process must be blocked right away because the resource it needs is not
available
Lazy invocation: Setting the
need_resched field of current to 1. Since a check on the value of this field is
always made before resuming the execution of a User Mode process, schedule(
)
will definitely be invoked
at some close future time.
Kernel/sched.c
asmlinkage void
schedule(void)
{
…
repeat_schedule:
/*
* Default process to select..
*/
next
= idle_task(this_cpu);
c =
-1000;
if
(prev->state == TASK_RUNNING)
goto still_running;
still_running_back:
list_for_each(tmp, &runqueue_head) {
p = list_entry(tmp, struct task_struct, run_list);
if (can_schedule(p, this_cpu)) {
int weight = goodness(p, this_cpu,
prev->active_mm);
if (weight > c)
c = weight, next = p;
}
}
/*
Do we need to re-calculate counters? */
if
(!c)
goto recalculate;
sched_data->curr = next;
…
recalculate:
{
struct task_struct *p;
spin_unlock_irq(&runqueue_lock);
read_lock(&tasklist_lock);
for_each_task(p)
p->counter = (p->counter >> 1) +
NICE_TO_TICKS(p->nice);
read_unlock(&tasklist_lock);
spin_lock_irq(&runqueue_lock);
}
goto
repeat_schedule;
still_running:
c =
goodness(prev, this_cpu, prev->active_mm);
next
= prev;
goto
still_running_back;
…
}