操作系统导论OSTEP 第28章作业答案 锁

问题2

linux.>  ./x86.py -p flag.s -M flag,count -R ax,bx -c
ARG seed 0
ARG numthreads 2
ARG program flag.s
ARG interrupt frequency 50
ARG interrupt randomness False
ARG procsched 
ARG argv 
ARG load address 1000
ARG memsize 128
ARG memtrace flag,count
ARG regtrace ax,bx
ARG cctrace False
ARG printstats False
ARG verbose False


 flag count      ax    bx          Thread 0                Thread 1         

    0     0       0     0   
    0     0       0     0   1000 mov  flag, %ax
    0     0       0     0   1001 test $0, %ax
    0     0       0     0   1002 jne  .acquire
    1     0       0     0   1003 mov  $1, flag
    1     0       0     0   1004 mov  count, %ax
    1     0       1     0   1005 add  $1, %ax
    1     1       1     0   1006 mov  %ax, count
    0     1       1     0   1007 mov  $0, flag
    0     1       1    -1   1008 sub  $1, %bx
    0     1       1    -1   1009 test $0, %bx
    0     1       1    -1   1010 jgt .top
    0     1       1    -1   1011 halt
    0     1       0     0   ----- Halt;Switch -----  ----- Halt;Switch -----  
    0     1       0     0                            1000 mov  flag, %ax
    0     1       0     0                            1001 test $0, %ax
    0     1       0     0                            1002 jne  .acquire
    1     1       0     0                            1003 mov  $1, flag
    1     1       1     0                            1004 mov  count, %ax
    1     1       2     0                            1005 add  $1, %ax
    1     2       2     0                            1006 mov  %ax, count
    0     2       2     0                            1007 mov  $0, flag
    0     2       2    -1                            1008 sub  $1, %bx
    0     2       2    -1                            1009 test $0, %bx
    0     2       2    -1                            1010 jgt .top
    0     2       2    -1                            1011 halt

问题4

生成不同的中断频率,运行结果会不同,仍然存在竞态。

问题5

程序test-and-set.s

.var mutex
.var count

.main
.top	

.acquire			# 获取锁
mov  $1, %ax        
xchg %ax, mutex     # atomic swap of 1 and mutex
test $0, %ax        # if we get 0 back: lock is free!
jne  .acquire       # if not, try again

# critical section
mov  count, %ax     # get the value at the address
add  $1, %ax        # increment it
mov  %ax, count     # store it back

# release lock
mov  $0, mutex		# 释放锁

# see if we're still looping
sub  $1, %bx
test $0, %bx
jgt .top	

halt

问题6

linux.> ./x86.py -p test-and-set.s -M mutex,count -R ax,bx -i 1 -c
linux.> ./x86.py -p test-and-set.s -M mutex,count -R ax,bx -i 6 -c
linux.> ./x86.py -p test-and-set.s -M mutex,count -R ax,bx -i 11 -c
linux.> ./x86.py -p test-and-set.s -M mutex,count -R ax,bx -i 16 -c
linux.> ./x86.py -p test-and-set.s -M mutex,count -R ax,bx -i 21 -c

# 上述命令执行结果如下

ARG seed 0
ARG numthreads 2
ARG program test-and-set.s
ARG interrupt frequency 1
ARG interrupt randomness False
ARG procsched 
ARG argv 
ARG load address 1000
ARG memsize 128
ARG memtrace mutex,count
ARG regtrace ax,bx
ARG cctrace False
ARG printstats False
ARG verbose False


mutex count      ax    bx          Thread 0                Thread 1         

    0     0       0     0   
    0     0       1     0   1000 mov  $1, %ax
    0     0       0     0   ------ Interrupt ------  ------ Interrupt ------  
    0     0       1     0                            1000 mov  $1, %ax
    0     0       1     0   ------ Interrupt ------  ------ Interrupt ------  
    1     0       0     0   1001 xchg %ax, mutex
    1     0       1     0   ------ Interrupt ------  ------ Interrupt ------  
    1     0       1     0                            1001 xchg %ax, mutex
    1     0       0     0   ------ Interrupt ------  ------ Interrupt ------  
    1     0       0     0   1002 test $0, %ax
    1     0       1     0   ------ Interrupt ------  ------ Interrupt ------  
    1     0       1     0                            1002 test $0, %ax
    1     0       0     0   ------ Interrupt ------  ------ Interrupt ------  
    1     0       0     0   1003 jne  .acquire
    1     0       1     0   ------ Interrupt ------  ------ Interrupt ------  
    1     0       1     0                            1003 jne  .acquire
    1     0       0     0   ------ Interrupt ------  ------ Interrupt ------  
    1     0       0     0   1004 mov  count, %ax
    1     0       1     0   ------ Interrupt ------  ------ Interrupt ------  
    1     0       1     0                            1000 mov  $1, %ax
    1     0       0     0   ------ Interrupt ------  ------ Interrupt ------  
    1     0       1     0   1005 add  $1, %ax
    1     0       1     0   ------ Interrupt ------  ------ Interrupt ------  
    1     0       1     0                            1001 xchg %ax, mutex
    1     0       1     0   ------ Interrupt ------  ------ Interrupt ------  
    1     1       1     0   1006 mov  %ax, count
    1     1       1     0   ------ Interrupt ------  ------ Interrupt ------  
    1     1       1     0                            1002 test $0, %ax
    1     1       1     0   ------ Interrupt ------  ------ Interrupt ------  
    0     1       1     0   1007 mov  $0, mutex
    0     1       1     0   ------ Interrupt ------  ------ Interrupt ------  
    0     1       1     0                            1003 jne  .acquire
    0     1       1     0   ------ Interrupt ------  ------ Interrupt ------  
    0     1       1    -1   1008 sub  $1, %bx
    0     1       1     0   ------ Interrupt ------  ------ Interrupt ------  
    0     1       1     0                            1000 mov  $1, %ax
    0     1       1    -1   ------ Interrupt ------  ------ Interrupt ------  
    0     1       1    -1   1009 test $0, %bx
    0     1       1     0   ------ Interrupt ------  ------ Interrupt ------  
    1     1       0     0                            1001 xchg %ax, mutex
    1     1       1    -1   ------ Interrupt ------  ------ Interrupt ------  
    1     1       1    -1   1010 jgt .top
    1     1       0     0   ------ Interrupt ------  ------ Interrupt ------  
    1     1       0     0                            1002 test $0, %ax
    1     1       1    -1   ------ Interrupt ------  ------ Interrupt ------  
    1     1       1    -1   1011 halt
    1     1       0     0   ----- Halt;Switch -----  ----- Halt;Switch -----  
    1     1       0     0   ------ Interrupt ------  ------ Interrupt ------  
    1     1       0     0                            1003 jne  .acquire
    1     1       0     0   ------ Interrupt ------  ------ Interrupt ------  
    1     1       1     0                            1004 mov  count, %ax
    1     1       1     0   ------ Interrupt ------  ------ Interrupt ------  
    1     1       2     0                            1005 add  $1, %ax
    1     1       2     0   ------ Interrupt ------  ------ Interrupt ------  
    1     2       2     0                            1006 mov  %ax, count
    1     2       2     0   ------ Interrupt ------  ------ Interrupt ------  
    0     2       2     0                            1007 mov  $0, mutex
    0     2       2     0   ------ Interrupt ------  ------ Interrupt ------  
    0     2       2    -1                            1008 sub  $1, %bx
    0     2       2    -1   ------ Interrupt ------  ------ Interrupt ------  
    0     2       2    -1                            1009 test $0, %bx
    0     2       2    -1   ------ Interrupt ------  ------ Interrupt ------  
    0     2       2    -1                            1010 jgt .top
    0     2       2    -1   ------ Interrupt ------  ------ Interrupt ------  
    0     2       2    -1                            1011 halt
ARG seed 0
ARG numthreads 2
ARG program test-and-set.s
ARG interrupt frequency 6
ARG interrupt randomness False
ARG procsched 
ARG argv 
ARG load address 1000
ARG memsize 128
ARG memtrace mutex,count
ARG regtrace ax,bx
ARG cctrace False
ARG printstats False
ARG verbose False


mutex count      ax    bx          Thread 0                Thread 1         

    0     0       0     0   
    0     0       1     0   1000 mov  $1, %ax
    1     0       0     0   1001 xchg %ax, mutex
    1     0       0     0   1002 test $0, %ax
    1     0       0     0   1003 jne  .acquire
    1     0       0     0   1004 mov  count, %ax
    1     0       1     0   1005 add  $1, %ax
    1     0       0     0   ------ Interrupt ------  ------ Interrupt ------  
    1     0       1     0                            1000 mov  $1, %ax
    1     0       1     0                            1001 xchg %ax, mutex
    1     0       1     0                            1002 test $0, %ax
    1     0       1     0                            1003 jne  .acquire
    1     0       1     0                            1000 mov  $1, %ax
    1     0       1     0                            1001 xchg %ax, mutex
    1     0       1     0   ------ Interrupt ------  ------ Interrupt ------  
    1     1       1     0   1006 mov  %ax, count
    0     1       1     0   1007 mov  $0, mutex
    0     1       1    -1   1008 sub  $1, %bx
    0     1       1    -1   1009 test $0, %bx
    0     1       1    -1   1010 jgt .top
    0     1       1    -1   1011 halt
    0     1       1     0   ----- Halt;Switch -----  ----- Halt;Switch -----  
    0     1       1     0   ------ Interrupt ------  ------ Interrupt ------  
    0     1       1     0                            1002 test $0, %ax
    0     1       1     0                            1003 jne  .acquire
    0     1       1     0                            1000 mov  $1, %ax
    1     1       0     0                            1001 xchg %ax, mutex
    1     1       0     0                            1002 test $0, %ax
    1     1       0     0                            1003 jne  .acquire
    1     1       0     0   ------ Interrupt ------  ------ Interrupt ------  
    1     1       1     0                            1004 mov  count, %ax
    1     1       2     0                            1005 add  $1, %ax
    1     2       2     0                            1006 mov  %ax, count
    0     2       2     0                            1007 mov  $0, mutex
    0     2       2    -1                            1008 sub  $1, %bx
    0     2       2    -1                            1009 test $0, %bx
    0     2       2    -1   ------ Interrupt ------  ------ Interrupt ------  
    0     2       2    -1                            1010 jgt .top
    0     2       2    -1                            1011 halt
ARG seed 0
ARG numthreads 2
ARG program test-and-set.s
ARG interrupt frequency 11
ARG interrupt randomness False
ARG procsched 
ARG argv 
ARG load address 1000
ARG memsize 128
ARG memtrace mutex,count
ARG regtrace ax,bx
ARG cctrace False
ARG printstats False
ARG verbose False


mutex count      ax    bx          Thread 0                Thread 1         

    0     0       0     0   
    0     0       1     0   1000 mov  $1, %ax
    1     0       0     0   1001 xchg %ax, mutex
    1     0       0     0   1002 test $0, %ax
    1     0       0     0   1003 jne  .acquire
    1     0       0     0   1004 mov  count, %ax
    1     0       1     0   1005 add  $1, %ax
    1     1       1     0   1006 mov  %ax, count
    0     1       1     0   1007 mov  $0, mutex
    0     1       1    -1   1008 sub  $1, %bx
    0     1       1    -1   1009 test $0, %bx
    0     1       1    -1   1010 jgt .top
    0     1       0     0   ------ Interrupt ------  ------ Interrupt ------  
    0     1       1     0                            1000 mov  $1, %ax
    1     1       0     0                            1001 xchg %ax, mutex
    1     1       0     0                            1002 test $0, %ax
    1     1       0     0                            1003 jne  .acquire
    1     1       1     0                            1004 mov  count, %ax
    1     1       2     0                            1005 add  $1, %ax
    1     2       2     0                            1006 mov  %ax, count
    0     2       2     0                            1007 mov  $0, mutex
    0     2       2    -1                            1008 sub  $1, %bx
    0     2       2    -1                            1009 test $0, %bx
    0     2       2    -1                            1010 jgt .top
    0     2       1    -1   ------ Interrupt ------  ------ Interrupt ------  
    0     2       1    -1   1011 halt
    0     2       2    -1   ----- Halt;Switch -----  ----- Halt;Switch -----  
    0     2       2    -1                            1011 halt
ARG seed 0
ARG numthreads 2
ARG program test-and-set.s
ARG interrupt frequency 16
ARG interrupt randomness False
ARG procsched 
ARG argv 
ARG load address 1000
ARG memsize 128
ARG memtrace mutex,count
ARG regtrace ax,bx
ARG cctrace False
ARG printstats False
ARG verbose False


mutex count      ax    bx          Thread 0                Thread 1         

    0     0       0     0   
    0     0       1     0   1000 mov  $1, %ax
    1     0       0     0   1001 xchg %ax, mutex
    1     0       0     0   1002 test $0, %ax
    1     0       0     0   1003 jne  .acquire
    1     0       0     0   1004 mov  count, %ax
    1     0       1     0   1005 add  $1, %ax
    1     1       1     0   1006 mov  %ax, count
    0     1       1     0   1007 mov  $0, mutex
    0     1       1    -1   1008 sub  $1, %bx
    0     1       1    -1   1009 test $0, %bx
    0     1       1    -1   1010 jgt .top
    0     1       1    -1   1011 halt
    0     1       0     0   ----- Halt;Switch -----  ----- Halt;Switch -----  
    0     1       1     0                            1000 mov  $1, %ax
    1     1       0     0                            1001 xchg %ax, mutex
    1     1       0     0                            1002 test $0, %ax
    1     1       0     0                            1003 jne  .acquire
    1     1       0     0   ------ Interrupt ------  ------ Interrupt ------  
    1     1       1     0                            1004 mov  count, %ax
    1     1       2     0                            1005 add  $1, %ax
    1     2       2     0                            1006 mov  %ax, count
    0     2       2     0                            1007 mov  $0, mutex
    0     2       2    -1                            1008 sub  $1, %bx
    0     2       2    -1                            1009 test $0, %bx
    0     2       2    -1                            1010 jgt .top
    0     2       2    -1                            1011 halt
ARG seed 0
ARG numthreads 2
ARG program test-and-set.s
ARG interrupt frequency 21
ARG interrupt randomness False
ARG procsched 
ARG argv 
ARG load address 1000
ARG memsize 128
ARG memtrace mutex,count
ARG regtrace ax,bx
ARG cctrace False
ARG printstats False
ARG verbose False


mutex count      ax    bx          Thread 0                Thread 1         

    0     0       0     0   
    0     0       1     0   1000 mov  $1, %ax
    1     0       0     0   1001 xchg %ax, mutex
    1     0       0     0   1002 test $0, %ax
    1     0       0     0   1003 jne  .acquire
    1     0       0     0   1004 mov  count, %ax
    1     0       1     0   1005 add  $1, %ax
    1     1       1     0   1006 mov  %ax, count
    0     1       1     0   1007 mov  $0, mutex
    0     1       1    -1   1008 sub  $1, %bx
    0     1       1    -1   1009 test $0, %bx
    0     1       1    -1   1010 jgt .top
    0     1       1    -1   1011 halt
    0     1       0     0   ----- Halt;Switch -----  ----- Halt;Switch -----  
    0     1       1     0                            1000 mov  $1, %ax
    1     1       0     0                            1001 xchg %ax, mutex
    1     1       0     0                            1002 test $0, %ax
    1     1       0     0                            1003 jne  .acquire
    1     1       1     0                            1004 mov  count, %ax
    1     1       2     0                            1005 add  $1, %ax
    1     2       2     0                            1006 mov  %ax, count
    0     2       2     0                            1007 mov  $0, mutex
    0     2       2    -1                            1008 sub  $1, %bx
    0     2       2    -1   ------ Interrupt ------  ------ Interrupt ------  
    0     2       2    -1                            1009 test $0, %bx
    0     2       2    -1                            1010 jgt .top
    0     2       2    -1                            1011 halt

此时代码总能按预期工作,但有时会导致CPU使用率不高。

问题7

./x86.py -p test-and-set.s -M mutex,count -R ax,bx -a bx=5 -P 1100111000111000111000 -i 10 -c

正确的事发生了。

问题8

linux.> cat peterson.s 
# array of 2 integers (each size 4 bytes)
# load address of flag into fx register
# access flag[] with 0(%fx,%index,4)
# where %index is a register holding 0 or 1
# index reg contains 0 -> flag[0], if 1->flag[1]
.var flag   2     

# global turn variable
.var turn

# global count
.var count

.main

# put address of flag into fx
lea flag, %fx

# assume thread ID is in bx (0 or 1, scale by 4 to get proper flag address)
mov %bx, %cx   # bx: self, now copies to cx
neg %cx        # cx: - self
add $1, %cx    # cx: 1 - self

.acquire
mov $1, 0(%fx,%bx,4)    # flag[self] = 1
mov %cx, turn           # turn       = 1 - self

.spin1
mov 0(%fx,%cx,4), %ax   # flag[1-self]
test $1, %ax            
jne .fini               # if flag[1-self] != 1, skip past loop to .fini

.spin2                  # just labeled for fun, not needed
mov turn, %ax
test %cx, %ax           # compare 'turn' and '1 - self'
je .spin1               # if turn==1-self, go back and start spin again

# fall out of spin
.fini

# do critical section now
mov count, %ax
add $1, %ax
mov %ax, count

.release
mov $0, 0(%fx,%bx,4)    # flag[self] = 0


# end case: make sure it's other's turn
mov %cx, turn           # turn       = 1 - self
halt

问题9

只有使用-a给%bx赋初值时锁才有效,否则可能会出现错误结果。

问题14

linux.> cat yield.s 
.var mutex
.var count

.main
.top	

.acquire
mov  $1, %ax        
xchg %ax, mutex     # atomic swap of 1 and mutex
test $0, %ax        # if we get 0 back: lock is free!
je .acquire_done    
yield               # if not, yield and try again
j .acquire
.acquire_done

# critical section
mov  count, %ax     # get the value at the address
add  $1, %ax        # increment it
mov  %ax, count     # store it back

# release lock
mov  $0, mutex

# see if we're still looping
sub  $1, %bx
test $0, %bx
jgt .top	

halt

分别调用命令:

linux.> ./x86.py -p yield.s -M mutex,count -R ax,bx -a bx=5 -P 1100111000111000111000 -i 10 -c
linux.> ./x86.py -p test-and-set.s -M mutex,count -R ax,bx -a bx=5 -P 1100111000111000111000 -i 10 -c

可以观察到在锁被占用时,yield.s主动放弃CPU,而test-and-set.s会自旋,浪费资源。

问题15

这是一个两阶段锁,其优点参考本章最后一节。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刷子c

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值