(past (signal-new-answer min-e))で達成可能なエネルギー値が更新され, min-eになったことを他のプロ セッサに連絡する. pastはfutureと同様の意味を持つが, 結果を受けとるため のreply boxを返さない. したがって処理の終了を明示的に検出しないことを 明示している.
さて, signal-new-answerの中で行なわれる処理を見る. 基本的には全 プロセッサに向けて, 更新処理を依頼する関数をfutureによって起動している だけであるが, それに加えて簡単なフロー制御を行なっている. これは, 特に 頻繁に解が更新されると思われる探索の初期段階において, 頻繁に更新メッセー ジが送られあうのを避けるためである. 具体的には, 一つのプロセッサは複数 の更新処理をオーバーラップして行なわないようにする. すなわちあるプロセッ サによるn-1回目の更新処理が完了するまで, n回目の更新処理を始めない. そのために, n回目の更新処理を行なう前にn-1回目の更新処理の返事を全 て待つ. ABCL/fでは以下のように実現する. ある更新処理の際に, 起動した futureの結果(reply box)を全てリストにつなげておき, 覚えておく. その次 の更新処理時に, そのリストの全要素に対してtouchを行なう. もし前回の更 新処理から十分時間が立っていればそのtouchはblockすることなく行なわれる 可能性が高い. 一方, 前回の更新処理から間もなく次の更新処理が行なわれよ うとした時には, まだ返事が返っていないプロセッサのところでblockして, 更新処理は後回しにされる. 以前の更新処理時のreply boxを覚えておくため に, オブジェクトを作り, その中にreply boxを格納する. 以下がそのオブジェ クトの定義である.
(defclass outstanding-signals-holder () ((list (future unit)) signals))インスタンス変数signalsが, まだtouchされていないreply boxを貯め ておくリストである. このオブジェクトが各プロセッサに一個ずつ作られ, 大 域変数*outstanding-signals*により参照される.
(defvar *outstanding-signals* (void outstanding-signals-holder))signal-new-answer自身の記述は以下のようになる.
(defun signal-new-answer (e) (declare (real e) (reply-type unit)) ;; 最初にlocalの*outstanding-signals*オブジェクトをupdateする. (signal-new-answer-local e) ;; 前回の更新時のreply boxをtouchする. (dolist (x (fetch-signals *outstanding-signals*)) (touch x)) ;; 各プロセッサの, *outstanding-signals*オブジェクトをfutureでupdateし, ;; 得られたreply boxを, ローカルな*outstanding-signals*オブジェクト ;; に格納する(次回の更新処理でtouchされる) (let ((rs '())) (declare ((list (future unit)) rs)) (dotimes (i *npe*) (unless (= i *pe*) (push (future (signal-new-answer-local e) :on i) rs))) (put-signals *outstanding-signals* rs)))