230 likes | 345 Views
Guidelines for Using SDL in Product Development. Frank Weil Motorola Global Software Group – Software Design Automation. Overview. General Recommendations for Design Models Recommendations on SDL Usage for Design Performance Considerations Platform Interfaces Portability Issues
E N D
Guidelinesfor Using SDLin Product Development Frank Weil Motorola Global Software Group – Software Design Automation
Overview • General Recommendations for Design Models • Recommendations on SDL Usage for Design • Performance Considerations • Platform Interfaces • Portability Issues • Example Models
SDL for Design Two inherent problems: • Bad things can happen behind the scenes • Deadlocks • Signal send to a dead / invalid / unreachable process • … • It is hard to prove correctness! • Syntactically/semantically correct models can be confusing • Subrange constants are ignored in data type definition • Unused signals, data types, variables, procedures, … • … • Excuse: “If they new the semantics better, it would not be confusing” • Obvious things should have obvious semantics
General Recommendations • Nondeterminism and Fairness • SDL has several nondeterministic features • A good design should be deterministic • Nondeterminism does not imply fairness • Abstraction • Everything should be made as simple as possible,but no simpler! - Albert Einstein • Model must capture concepts, not irrelevant details
Examples Models • First, a bad example • Then, a good example for comparison • Read the paper for details (please?)
system SAM04_bad_example 1(1) newtype call_info struct header Integer; path Natural; dest destination_select; toggle Boolean; payload payload_t; signal packet(call_info); level Real; signal new_packet(call_info); endnewtype; signal control(Natural); signal updates(update_type); syntype destination_select = Destinations signal status(STATUS); constants 0 : 255 signal command(cmd_type, Buffer); endsyntype; signal config; syntype update_type = Integer constants 0, 2, 4, 8 endsyntype; newtype STATUS literals standby, current, update endnewtype; syntype update_interval = Natural constants -10 : 10 endsyntype; syntype cmd_type = Charstring endsyntype; syntype Buffer = Charstring endsyntype; syntype Destinations = Integer constants 1 : 100 endsyntype; syntype payload_t = Charstring constants size(10) endsyntype; signallist inbound_signals = packet, control, command, config; signallist outbound_signals = updates, new_packet; outbound1 (outbound_signals) switch traffic outbound2 (inbound_signals) (outbound_signals)
block switch 1(1) inbound traffic router (inbound_signals) internal (outbound_signals) packet outbound1 odd handler(0) even outbound2 (outbound_signals)
process router synonym 911 cmd_type = 'EMERGENCY'; procedure log; synonym REMOVE_CMD cmd_type = 'REMOVE'; fpar in stat Integer; synonym max_proc processes = 5; external; syntype processes = Integer timer TIM; dcl i, d, pow Integer; constants 1 : 5 dcl j processes; endsyntype; dcl ci, ci_tmp call_info; dcl ct cmd_type; dcl ts Boolean := false; dcl b Buffer; /* 16-bit unsigned int, LSB first */ j := 1 d := 1 (false) (true) j <= max_proc set(100, TIM) Handler 'done with initialization' j := j + 1 idle 1(2)
process router idle TIM packet(ci) command(ct, b) (REMOVE_CMD) log(1) ci_tmp := ci ct (911) set(now+7.325, TIM) d := num(b(0)) ts := not ts idle idle idle idle i := 1 ci_tmp!dest := d pow := 2 (false) ci_tmp!toggle := ts i <= 15 (true) packet(ci_tmp) via internal d := d + num(b(i)) * pow pow := pow * 2 i := i + 1 2(2)
process handler 1(1) dcl ci call_info; packet(ci) ci!path (0) (1) ci!payload := 'even' ci!payload := 'odd' ci!toggle ci!toggle (true) (true) (false) (false) ci!payload := ci!payload // 'T' ci!payload :=ci!payload // 'T ' idle idle idle ci!payload := ci!payload // 'F' ci!payload := ci!payload // 'F ' else new_packet(ci) Via even ci!level = 3.0 (true) ci!level := ci!level * 5 ci!header else (0) new_packet(ci) VIA odd
synonym 911 cmd_type = 'EMERGENCY'; synonym REMOVE_CMD cmd_type = 'REMOVE'; number as identifier Charstring instead of enum process router 1(2) synonym max_proc processes = 5; syntype processes = Integer timer TIM; dcl i, d, pow Integer; constants 1 : 5 dcl j processes; endsyntype; dcl ci, ci_tmp call_info; dcl ct cmd_type; dcl ts Boolean := false; dcl b Buffer; /* 16-bit unsigned int, LSB first */ j := 1 can be decluttered d := 1 (false) (true) loop control is wrong j <= max_proc Time literal case insensitivity set(100, TIM) Handler informal text as comment 'done with initialization' j := j + 1 idle
process router idle TIM packet(ci) command(ct, b) (REMOVE_CMD) log(1) ci_tmp := ci ct (911) ts := not ts set(now+7.325, TIM) d := num(b(0)) idle idle idle idle i := 1 ci_tmp!dest := d pow := 2 (false) ci_tmp!toggle := ts i <= 15 (true) packet(ci_tmp) via internal d := d + num(b(i)) * pow pow := pow * 2 i := i + 1 2(2) procedure log; fpar in stat Integer; C reserved word external; marshaling invalid String access copy of large data structure Duration precision possibly incompatible ranges ambiguous signal send can be decluttered
process handler 1(1) dcl ci call_info; packet(ci) ci!path (0) (1) ci!payload := 'even' ci!payload := 'odd' idle idle idle ci!toggle ci!toggle (true) (true) (false) (false) ci!payload := ci!payload // 'T' ci!payload :=ci!payload // 'T ' ci!payload := ci!payload // 'F' ci!payload := ci!payload // 'F ' else new_packet(ci) Via even ci!level = 3.0 (true) ci!level := ci!level * 5 ci!header else (0) new_packet(ci) VIA odd can be decluttered Charstring size constraint violation Real equality case insensitivity send to a dead process
block switch 1(1) inbound traffic router (inbound_signals) internal (outbound_signals) packet outbound1 odd handler(0) even outbound2 (outbound_signals) C keyword no max number of process instances
1(1) system SAM04_bad_example newtype call_info struct header Integer; underconstrained sort path Natural; dest destination_select; toggle Boolean; payload payload_t; signal packet(call_info); level Real; signal new_packet(call_info); endnewtype; signal control(Natural); signal updates(update_type); syntype destination_select = Destinations signal not used in this version signal status(STATUS); constants 0 : 255 signal command(cmd_type, Buffer); endsyntype; signal config; syntype update_type = Integer constants 0, 2, 4, 8 nonsensical / confusing data type definitions endsyntype; newtype STATUS literals standby, current, update endnewtype; unused signals and data types syntype update_interval = Natural constants -10 : 10 endsyntype; marshaling syntype cmd_type = Charstring endsyntype; syntype Buffer = Charstring endsyntype; unbounded / incorrectly bounded aggregate data types syntype Destinations = Integer constants 1 : 100 endsyntype; syntype payload_t = Charstring constants size(10) endsyntype; signallist inbound_signals = packet, control, command, config; signallist outbound_signals = updates, new_packet; outbound1 (outbound_signals) switch traffic outbound2 (inbound_signals) (outbound_signals) C keyword
system SAM04_good_example 1(1) newtype call_info struct header Integer; path path_t; dest destination_select; toggle Boolean; signal packet(call_info); payload payload_t; signal new_packet(call_info); level Real; signal emergency(Integer); endnewtype; signal remove; signal config; syntype path_t = Natural constants 0 : 1 endsyntype; syntype destination_select = Natural constants 0 : 255 endsyntype; syntype payload_t = Charstring constants size(5) endsyntype; signallist inbound_signals = packet, emergency, remove, config; signallist outbound_signals = new_packet; outbound1 traffic (outbound_signals) switcher (inbound_signals) outbound2 (outbound_signals)
1(1) block switcher synonym max_proc Natural = 5; signal dead(processes), okay; syntype processes = Natural constants 1 : max_proc endsyntype; inbound traffic router(1,1) (inbound_signals) dead internal packet, (outbound_signals) outbound1 okay odd handler (0, max_proc) even outbound2 (outbound_signals)
process router 1(2) timer TIM; dcl d destination_select := 1; dcl j processes := 1; dcl ci call_info; dcl ts Boolean := false; dcl count processes := max_proc; set_next_handler newtype pids Array(processes, Pid) endnewtype; dcl handlers pids; dcl next_handler processes := 1; procedure heartbeat; fpar in stat Integer; external; * config handled in phase 2 handler(j) - handlers(j) := offspring (true) (false) j < max_proc j := j + 1 set(now + 100000, TIM) done with initialization idle
process router 2(2) idle dead(j) TIM packet(ci) emergency(d) remove ci!dest := d, okay to sender heartbeat(1) ts := not ts ci!toggle := ts (1) packet(ci) count set(now+7325, TIM) to handlers(next_handler) else handlers(j) := Null, set_next_handler count := count - 1 -
process handler 1(1) dcl ci call_info; ; fpar me processes; dying build_payload okay * near idle - packet(ci) ci!payload := call build_payload(ci!path, ci!toggle) (0) (1) ci!path (false) call near(ci!level, 3.0) (true) ci!level := ci!level * 5 new_packet(ci) via even new_packet(ci) via odd else ci!header (0) dead(me) dying -
procedure build_payload 1(1) ; fpar in path path_t, in toggle Boolean; syntype position = Integer returns payload_t; constants 4 : 5 endsyntype; dcl insert position; dcl payload payload_t; (0) (1) path payload := 'even ', payload := 'odd ', insert := 5 insert := 4 toggle (true) (false) payload(insert) := 'T' payload(insert) := 'F' payload
procedure near 1(1) ; fpar in a Real, in b Real; synonym epsilon Real = 0.0001; returns Boolean; fix((a - b) / epsilon) = 0