Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
CSEP551
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Krishna Vinnakota
CSEP551
Commits
00e57115
Commit
00e57115
authored
15 years ago
by
Russ Cox
Browse files
Options
Downloads
Patches
Plain Diff
more doc tweaks
parent
2c5f7aba
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
TRICKS
+13
-13
13 additions, 13 deletions
TRICKS
pipe.c
+20
-20
20 additions, 20 deletions
pipe.c
proc.c
+18
-20
18 additions, 20 deletions
proc.c
web/l-coordination.html
+1
-1
1 addition, 1 deletion
web/l-coordination.html
with
52 additions
and
54 deletions
TRICKS
+
13
−
13
View file @
00e57115
...
...
@@ -4,6 +4,9 @@ might be worth pointing out in a longer explanation or in class.
---
[2009/07/12: No longer relevant; forkret1 changed
and this is now cleaner.]
forkret1 in trapasm.S is called with a tf argument.
In order to use it, forkret1 copies the tf pointer into
%esp and then jumps to trapret, which pops the
...
...
@@ -45,21 +48,21 @@ always.
There is a (harmless) race in pushcli, which does
eflags = read
_
eflags();
eflags = readeflags();
cli();
if(c
pus[cpu()].
ncli++ == 0)
c
pus[cpu()].
intena = eflags & FL_IF;
if(c
->
ncli++ == 0)
c
->
intena = eflags & FL_IF;
Consider a bottom-level pushcli.
If interrupts are disabled already, then the right thing
happens: read_eflags finds that FL_IF is not set,
and intena =
1
. If interrupts are enabled, then
and intena =
0
. If interrupts are enabled, then
it is less clear that the right thing happens:
the read
_
eflags can execute, then the process
the readeflags can execute, then the process
can get preempted and rescheduled on another cpu,
and then once it starts running, perhaps with
interrupts disabled (can happen since the scheduler
only
dis
ables interrupts once per scheduling loop,
only
en
ables interrupts once per scheduling loop,
not every time it schedules a process), it will
incorrectly record that interrupts *were* enabled.
This doesn't matter, because if it was safe to be
...
...
@@ -112,17 +115,13 @@ processors will need it.
---
The code in
sys_
fork needs to read np->pid before
The code in fork needs to read np->pid before
setting np->state to RUNNABLE.
int
sys_
fork(void)
fork(void)
{
int pid;
struct proc *np;
if((np = copyproc(cp)) == 0)
return -1;
...
pid = np->pid;
np->state = RUNNABLE;
return pid;
...
...
@@ -134,3 +133,4 @@ get reused for a different process (with a new pid), all
before the return statement. So it's not safe to just do
"return np->pid;".
This works because proc.h marks the pid as volatile.
This diff is collapsed.
Click to expand it.
pipe.c
+
20
−
20
View file @
00e57115
...
...
@@ -9,12 +9,12 @@
#define PIPESIZE 512
struct
pipe
{
int
readopen
;
// read fd is still open
int
writeopen
;
// write fd is still open
uint
writep
;
// next index to write
uint
readp
;
// next index to read
struct
spinlock
lock
;
char
data
[
PIPESIZE
];
uint
nread
;
// number of bytes read
uint
nwrite
;
// number of bytes written
int
readopen
;
// read fd is still open
int
writeopen
;
// write fd is still open
};
int
...
...
@@ -30,8 +30,8 @@ pipealloc(struct file **f0, struct file **f1)
goto
bad
;
p
->
readopen
=
1
;
p
->
writeopen
=
1
;
p
->
write
p
=
0
;
p
->
read
p
=
0
;
p
->
n
write
=
0
;
p
->
n
read
=
0
;
initlock
(
&
p
->
lock
,
"pipe"
);
(
*
f0
)
->
type
=
FD_PIPE
;
(
*
f0
)
->
readable
=
1
;
...
...
@@ -60,10 +60,10 @@ pipeclose(struct pipe *p, int writable)
acquire
(
&
p
->
lock
);
if
(
writable
){
p
->
writeopen
=
0
;
wakeup
(
&
p
->
read
p
);
wakeup
(
&
p
->
n
read
);
}
else
{
p
->
readopen
=
0
;
wakeup
(
&
p
->
write
p
);
wakeup
(
&
p
->
n
write
);
}
if
(
p
->
readopen
==
0
&&
p
->
writeopen
==
0
)
{
release
(
&
p
->
lock
);
...
...
@@ -80,19 +80,19 @@ pipewrite(struct pipe *p, char *addr, int n)
acquire
(
&
p
->
lock
);
for
(
i
=
0
;
i
<
n
;
i
++
){
while
(
p
->
write
p
==
p
->
read
p
+
PIPESIZE
)
{
while
(
p
->
n
write
==
p
->
n
read
+
PIPESIZE
)
{
//DOC: pipewrite-full
if
(
p
->
readopen
==
0
||
cp
->
killed
){
release
(
&
p
->
lock
);
return
-
1
;
}
wakeup
(
&
p
->
read
p
);
sleep
(
&
p
->
write
p
,
&
p
->
lock
);
wakeup
(
&
p
->
n
read
);
sleep
(
&
p
->
n
write
,
&
p
->
lock
);
//DOC: pipewrite-sleep
}
p
->
data
[
p
->
write
p
++
%
PIPESIZE
]
=
addr
[
i
];
p
->
data
[
p
->
n
write
++
%
PIPESIZE
]
=
addr
[
i
];
}
wakeup
(
&
p
->
read
p
);
wakeup
(
&
p
->
n
read
);
//DOC: pipewrite-wakeup1
release
(
&
p
->
lock
);
return
i
;
return
n
;
}
int
...
...
@@ -101,19 +101,19 @@ piperead(struct pipe *p, char *addr, int n)
int
i
;
acquire
(
&
p
->
lock
);
while
(
p
->
read
p
==
p
->
write
p
&&
p
->
writeopen
){
while
(
p
->
n
read
==
p
->
n
write
&&
p
->
writeopen
){
//DOC: pipe-empty
if
(
cp
->
killed
){
release
(
&
p
->
lock
);
return
-
1
;
}
sleep
(
&
p
->
read
p
,
&
p
->
lock
);
sleep
(
&
p
->
n
read
,
&
p
->
lock
);
//DOC: piperead-sleep
}
for
(
i
=
0
;
i
<
n
;
i
++
){
if
(
p
->
read
p
==
p
->
write
p
)
for
(
i
=
0
;
i
<
n
;
i
++
){
//DOC: piperead-copy
if
(
p
->
n
read
==
p
->
n
write
)
break
;
addr
[
i
]
=
p
->
data
[
p
->
read
p
++
%
PIPESIZE
];
addr
[
i
]
=
p
->
data
[
p
->
n
read
++
%
PIPESIZE
];
}
wakeup
(
&
p
->
write
p
);
wakeup
(
&
p
->
n
write
);
//DOC: piperead-wakeup
release
(
&
p
->
lock
);
return
i
;
}
This diff is collapsed.
Click to expand it.
proc.c
+
18
−
20
View file @
00e57115
...
...
@@ -290,8 +290,8 @@ sleep(void *chan, struct spinlock *lk)
// guaranteed that we won't miss any wakeup
// (wakeup runs with ptable.lock locked),
// so it's okay to release lk.
if
(
lk
!=
&
ptable
.
lock
){
acquire
(
&
ptable
.
lock
);
if
(
lk
!=
&
ptable
.
lock
){
//DOC: sleeplock0
acquire
(
&
ptable
.
lock
);
//DOC: sleeplock1
release
(
lk
);
}
...
...
@@ -304,7 +304,7 @@ sleep(void *chan, struct spinlock *lk)
cp
->
chan
=
0
;
// Reacquire original lock.
if
(
lk
!=
&
ptable
.
lock
){
if
(
lk
!=
&
ptable
.
lock
){
//DOC: sleeplock2
release
(
&
ptable
.
lock
);
acquire
(
lk
);
}
...
...
@@ -393,7 +393,6 @@ exit(void)
}
// Jump into the scheduler, never to return.
cp
->
killed
=
0
;
cp
->
state
=
ZOMBIE
;
sched
();
panic
(
"zombie exit"
);
...
...
@@ -412,22 +411,21 @@ wait(void)
// Scan through table looking for zombie children.
havekids
=
0
;
for
(
p
=
ptable
.
proc
;
p
<
&
ptable
.
proc
[
NPROC
];
p
++
){
if
(
p
->
state
==
UNUSED
)
if
(
p
->
parent
!=
cp
)
continue
;
if
(
p
->
parent
==
cp
){
havekids
=
1
;
if
(
p
->
state
==
ZOMBIE
){
// Found one.
kfree
(
p
->
mem
,
p
->
sz
);
kfree
(
p
->
kstack
,
KSTACKSIZE
);
pid
=
p
->
pid
;
p
->
state
=
UNUSED
;
p
->
pid
=
0
;
p
->
parent
=
0
;
p
->
name
[
0
]
=
0
;
release
(
&
ptable
.
lock
);
return
pid
;
}
havekids
=
1
;
if
(
p
->
state
==
ZOMBIE
){
// Found one.
pid
=
p
->
pid
;
kfree
(
p
->
mem
,
p
->
sz
);
kfree
(
p
->
kstack
,
KSTACKSIZE
);
p
->
state
=
UNUSED
;
p
->
pid
=
0
;
p
->
parent
=
0
;
p
->
name
[
0
]
=
0
;
p
->
killed
=
0
;
release
(
&
ptable
.
lock
);
return
pid
;
}
}
...
...
@@ -438,7 +436,7 @@ wait(void)
}
// Wait for children to exit. (See wakeup1 call in proc_exit.)
sleep
(
cp
,
&
ptable
.
lock
);
sleep
(
cp
,
&
ptable
.
lock
);
//DOC: wait-sleep
}
}
...
...
This diff is collapsed.
Click to expand it.
web/l-coordination.html
+
1
−
1
View file @
00e57115
...
...
@@ -47,7 +47,7 @@
<h3>
Sleep and wakeup - usage
</h3>
Let's consider implementing a producer/consumer queue
(like a pipe) that can be used to hold a single non-null
char
pointer:
(like a pipe) that can be used to hold a single non-null pointer:
<pre>
struct pcq {
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment