サイズ固定・非同期・確保したサイズの限界まで使えるキュー
generic type Element_Type is private; package Fixed_Queues is type Element_Array is array(Positive range <>) of Element_Type; protected type Queue(Max_Length : Positive) is function Length return Natural; entry Put(Item : in Element_Type); entry Get(Item : out Element_Type); private Items : Element_Array(1 .. Max_Length); Head : Positive := 1; Tail : Positive := 1; Count : Natural := 0; end Queue; end Fixed_Queues;
package body Fixed_Queues is protected body Queue is function Length return Natural is begin return Count; end Length; entry Put(Item : in Element_Type) when Count < Max_Length is begin Items(Head) := Item; Count := Count + 1; Head := Head + 1; if Head > Items'Last then Head := Items'First; end if; end Put; entry Get(Item : out Element_Type) when Count > 0 is begin Item := Items(Tail); Count := Count - 1; Tail := Tail + 1; if Tail > Items'Last then Tail := Items'First; end if; end Get; end Queue; end Fixed_Queues;
protected型のentryは条件を満たした順に直列化されて実行されることが言語仕様で保証されているため……空の時にGetを呼んだりすると他からPutされるまで待ったりしますし、満杯の時にPutを呼んだりすると空くまで待ったりしますし……ああっ、石を投げないでっ。
結局何が言いたいかというと、Cωが向かっている道はAdaが10年以上前に通過した道だ、と……まあ……ええと……。
白状します。http://d.hatena.ne.jp/w_o/20060419#p1読んで私も前々からどうにかならんかなー思ってたのでなんかやろうとしたのですが、http://d.hatena.ne.jp/methane/20060419/1145460834に完敗です。