embedded - Semaphore in Ada -
this assignment , have been asked implement semaphore in ada description below.
however have implemented semaphore.adb
, called semaphore in producerconsumer_sem.adb
created.
i output following.
i'm not sure if initialization of semaphore correct
s: countingsemaphore(1,1);
.i don't know call
s.wait
,s.signal
randomly calleds.wait
before producer put item in bufferx := i;
,s.signal
afterx := i;
. correct way?
producer-consumer problem program
producerconsumer.adb
implements non-reliable implemen- tation of producer-consumer problem, data lost. in following, use 3 different communication mechanisms achieve reliable implementation of producer-consumer problem.semaphore
the ada language not directly provide library functions semaphore. however, semaphores can implemented means of protected object. create package specification semaphore in file semaphores.ads , corresponding package body in file
semaphores.adb
implements counting semaphore. skeletons package available on course page.use semaphore package reliable implementation of producer- consumer problem. modify file
producerconsumer.adb
, save final codeproducerconsumer_sem.adb
. in order use semaphore package shall installed in same directoryproducerconsumer_sem.adb
. can accessed by
with semaphores;
use semaphores;
the output:
output: 1 1 1 2 2 3 4 4 5 6 6 7 7 8 9 9 9 10 11 11 11 12 12 13 13 13 14 15 15 16 16 17 18 18 18 19 20 20 21 21 22 22 23 24 24 24 24 25 25 26 27 27 28 29 29 30 30 31 31 32 32 33 33 33 34 35 35 35 36 36 37 37 37 38 38 38 39 40 40 40
the package
package semaphores protected type countingsemaphore(max: natural; initial: natural) entry wait; entry signal; private count : natural := initial; maxcount : natural := max; end countingsemaphore; end semaphores;
the semaphore implemented semaphores.adb
.
package body semaphores protected body countingsemaphore entry wait when count > 0 begin count := count - 1; end wait; entry signal when count < maxcount begin count := count + 1; end signal; end countingsemaphore; end semaphores;
the producerconsumer_sem.adb
with ada.text_io; use ada.text_io; ada.real_time; use ada.real_time; ada.numerics.discrete_random; semaphores; use semaphores; procedure producerconsumer_sem x : integer; -- shared variable n : constant integer := 40; -- number of produced , comsumed variables s: countingsemaphore(1,1); --s1: countingsemaphore(1,1); pragma volatile(x); -- volatile object reads , updates of -- object whole performed directly -- memory (ada reference manual, c.6) --random delays subtype delay_interval integer range 50..250; package random_delay new ada.numerics.discrete_random (delay_interval); use random_delay; g : generator; task producer; task consumer; task body producer next : time; begin next := clock; in 1..n loop -- write x s.wait; x := i; s.signal; --next 'release' in 50..250ms next := next + milliseconds(random(g)); put_line(integer'image(x)); delay until next; end loop; end; task body consumer next : time; begin next := clock; in 1..n loop -- read x s.wait; put_line(integer'image(x)); s.signal; next := next + milliseconds(random(g)); delay until next; end loop; end; begin -- main task null; end producerconsumer_sem;
on macos, fsf gcc 7.1.0 , gnat gpl 2017, changed put_line
s put
s , got pretty-much answer state in question.
the question says create semaphore.ads
, .adb
. work on windows, , may work on macos, won’t work on linux, because of gnat’s file naming convention (see end of this; it’s idea habit of using lower-case file names).
if want ensure 1 task has access x
@ time, don’t think there’s wrong wait
, signal
calls, though when put delay 0.1
@ beginning of producer
, first value output 151619216 (because x
isn’t initialized). however! if point communicate 1 update x @ time (as implied names producer/consumer), should
- initialize semaphore count of 0 (and max of 1). makes binary semaphore.
- in
consumer
,wait
(i.e. removesignal
) - in
producer
,signal
(i.e. removewait
). also, removeput
avoid confusion!
Comments
Post a Comment