1function lqn=QN2LQN(model)
3lqn = LayeredNetwork(model.getName());
6PH = Host(lqn, model.getName(), Inf, SchedStrategy.INF); % pseudo host
8 inchain = sn.inchain{c};
9 RT{c} = Task(lqn,[
'RefTask_',num2str(c)], sum(sn.njobs(inchain)), SchedStrategy.REF).on(PH); % reference task
for chain c
10 RE{c} = Entry(lqn,[
'Chain_',num2str(c)]).on(
RT{c}); % entry on reference task
for chain c
15 case {NodeType.Queue, NodeType.Delay}
16 P{i} = Host(lqn, sn.nodenames{i}, sn.nservers(sn.nodeToStation(i)), SchedStrategy.fromId(sn.sched(sn.nodeToStation(i))));
17 T{i} = Task(lqn,[
'T_',sn.nodenames{i}], Inf, SchedStrategy.INF).on(
P{i});
19 c = find(sn.chains(:,r)); % chain of
class r
21 E{i,r} = Entry(lqn, [
'E',num2str(i),
'_',num2str(r)]).on(T{i});
22 A{i,r} = Activity(lqn, [
'Q',num2str(i),
'_',num2str(r)], model.nodes{i}.getServiceProcess(model.classes{r})).on(T{i}).boundTo(E{i,r}).repliesTo(E{i,r});
25 case {NodeType.ClassSwitch, NodeType.Router, NodeType.Logger}
26 % no-op: passthrough routing
nodes
27 case {NodeType.Source, NodeType.Sink}
28 % no-op: chain boundary
nodes
29 case {NodeType.Fork, NodeType.Join}
30 % no-op: synchronization
nodes, precedences added later
34PA = cell(sn.nchains, sn.nnodes, sn.nclasses);
35boundToRE = cell(1,sn.nchains);
38 case {NodeType.ClassSwitch, NodeType.Router, NodeType.Logger}
40 c = find(sn.chains(:,r)); % chain of
class r
41 if any(sn.rtnodes(:, ((i-1)*sn.nclasses + r))>0)
42 PA{c,i,r} = Activity(lqn, [
'CS',
'_',num2str(c),
'_',num2str(i),
'_',num2str(r)], Immediate()).on(
RT{c}); % pseudo-activity in ref task
45 case {NodeType.Fork, NodeType.Join}
47 c = find(sn.chains(:,r)); % chain of
class r
48 if any(sn.rtnodes(:, ((i-1)*sn.nclasses + r))>0)
49 PA{c,i,r} = Activity(lqn, [
'FJ',
'_',num2str(c),
'_',num2str(i),
'_',num2str(r)], Immediate()).on(
RT{c}); % pseudo-activity
for fork/join
52 case {NodeType.Queue, NodeType.Delay}
54 c = find(sn.chains(:,r)); % chain of
class r
56 inchain = sn.inchain{c};
57 if i == sn.refstat(inchain(1)) && r == inchain(1)
58 PA{c,i,r} = Activity(lqn, [
'A',num2str(i),
'_',num2str(r)], Immediate()).on(
RT{c}).boundTo(RE{c}).synchCall(E{i,r}); % pseudo-activity in ref task
61 PA{c,i,r} = Activity(lqn, [
'A',num2str(i),
'_',num2str(r)], Immediate()).on(
RT{c}).synchCall(E{i,r}); % pseudo-activity in ref task
63 %
RT{c}.addPrecedence(ActivityPrecedence.Serial(PN{c,i},PA{i,r}));
66 case {NodeType.Source, NodeType.Sink}
67 % no-op: chain boundary
nodes
71usedInORFork = zeros(sn.nnodes,sn.nclasses);
72routingNodeTypes = [NodeType.Queue, NodeType.Delay, NodeType.ClassSwitch, NodeType.Router, NodeType.Logger, NodeType.Fork, NodeType.Join];
74 inchain = sn.inchain{c};
75 %refstat = sn.refstat(inchain(1));
77 if ~ismember(sn.nodetype(i), routingNodeTypes)
84 if ~ismember(sn.nodetype(j), routingNodeTypes)
87 % Skip Join destinations - handled by AND-Join precedences below
88 if sn.nodetype(j) == NodeType.Join
92 pr = sn.rtnodes((i-1)*sn.nclasses + r, (j-1)*sn.nclasses + s);
93 if pr>0 && any(sn.rtnodes(:, ((i-1)*sn.nclasses + r))>0)
94 if ~isempty(boundToRE{c})
95 if boundToRE{c}(1)==j && boundToRE{c}(2)==s
96 if ~isempty(PA{c,i,r})
97 orfork_prec{end+1} = Activity(lqn, [
'End_',num2str(c),
'_',num2str(i),
'_',num2str(r)], Immediate()).on(
RT{c});
98 orfork_prob(end+1)= pr;
101 orfork_prec{end+1} = PA{c,j,s};
102 orfork_prob(end+1) = pr;
108 if ~isempty(orfork_prec)
109 if ~isempty(PA{c,i,r})
110 if sn.nodetype(i) == NodeType.Fork
111 % Fork node: AND-Fork (all branches taken simultaneously)
112 RT{c}.addPrecedence(ActivityPrecedence.AndFork(PA{c,i,r}, orfork_prec));
114 RT{c}.addPrecedence(ActivityPrecedence.OrFork(PA{c,i,r}, orfork_prec, orfork_prob));
116 usedInORFork(i,r) = usedInORFork(i,r) + 1;
123% AND-Join precedences
for Join
nodes
125 inchain = sn.inchain{c};
127 if sn.nodetype(j) ~= NodeType.Join
131 if isempty(PA{c,j,s})
136 if ~ismember(sn.nodetype(i), routingNodeTypes)
140 pr = sn.rtnodes((i-1)*sn.nclasses + r, (j-1)*sn.nclasses + s);
141 if pr > 0 && ~isempty(PA{c,i,r})
142 join_pre{end+1} = PA{c,i,r};
146 if length(join_pre) > 1
147 RT{c}.addPrecedence(ActivityPrecedence.AndJoin(join_pre, PA{c,j,s}));
148 elseif length(join_pre) == 1
149 RT{c}.addPrecedence(ActivityPrecedence({join_pre{1}.getName},{PA{c,j,s}.getName}));