15.APR.2012/HvM; 21.AUG.2013/HvM

 9. Het volgordeprobleem en een machineslag

Het volgordeprobleem
Het komt zo vaak voor: u heeft alles goed geprogrammeerd, maar het werkt niet. En wat u ook zoekt, u komt er niet achter waar het probleem zit. Dikke kans dat u in zo'n geval heeft te maken met het beruchte volgorde­probleem.

Het volgordeprobleem heeft te maken met de eigenschap van CCOL dat elementen die worden bestuurd, niet direct leiden tot het doorgeven van signalen die als een keten op elkaar moeten reageren. Dat zou wel in een event-gerichte programmeertaal gebeuren, maar zo zit CCOL nu eenmaal niet in elkaar. Anders gezegd: tussen actie en reactie zit altijd een heel korte tijd: een machineslag.

Een machineslag is het doorlopen van de gehele applicatie, inclusief alle systeemsoftware die tot de standaardsoftware van CCOL behoort. In die systeemsoftware worden bijvoorbeeld de groen-geel-rood-volgorde netjes doorlopen, de timers opgehoogd, de detectie-informatie binnengehaald en alle sturingen van fasecycli naar de CVN-interface overgezet. Binnen een machineslag hoort ook de afhandeling die de procesbesturing nog moet doen om al die informatie te verwerken: de lichtbeelden moeten worden aangestuurd, de actuele detectie-informatie moet op de interface worden klaargezet, de systeemklokken moeten worden bijgewerkt, het bedienpaneel moet worden gecheckt op nieuwe instructies, de commandoparser moet worden afgewerkt, de bedrijfsklok moet op nieuwe commando's worden getoetst, enzovoorts, enzovoorts, enzovoorts. Pas dáárna komt uw CCOL-applicatie eindelijk weer aan bod. Eén zo'n cyclus noemen we een machineslag, ook wel een systeemronde.

Daartussen kan veel gebeuren. Daardoor kan uw programma wel eens anders verlopen dan u had gewenst. U krijgt dan te maken met het volgordeprobleem!

Primair Gerealiseerd
Een berucht volgordeprobleem in CCOL is het SG en het PG (StartGroen en Primair Gerealiseerd; dit komt voor bij het gebruik van de modulestructuur). Wanneer we op het moment van startgroen willen weten of de betreffende fasecyclus primair is gerealiseerd kunnen we NIET volstaan met het volgende:

if (SG[fc05] && PG[fc05]) ...

Dit zal fout gaan doordat de PG pas één machineslag láter opkomt dan SG. Dus zodra PG opkomt, dan is SG nét voorbij!
In dit geval is het volgordeprobleem overigens goed te ondervangen door het statement te veranderen in:

if (SG[fc05] && PR[fc05]) ...(Primaire Realisatie)

Starten van een element
Een ander volgordeprobleem treedt op bij het starten van een element, bijvoorbeeld een tijdelement of een hulpwaarde.
De volgende programmacode zal pas na een extra machineslag leiden tot een aanvraag voor fc42:

IH[h42bus] = SD[dsi42bus];
A[fc42] |= H[h42bus];

In deze programmacode wordt in de eerste regel bij het inmelden van een bus de hulpwaarde opgezet. Maar doordat CCOL eerst nog een machineslag nodig heeft om als reactie daarop de H te besturen, komt de H dus circa 0,1 seconde láter op dan de SD. En wéér een machineslag later komt pas de aanvraag.
Dit probleem is te ondervangen door niet de H op te vragen maar rechtstreeks de IH:

IH[h42bus] |= SD[dsi42bus];
A[fc42] |= IH[h42bus];

Bedenk echter wel dat in uw programma de statements voorafgaand aan deze programmacode de IH nog níet TRUE is, en dus eventuele statements daarboven toch nog een machineslag nodig hebben om te kunnen reageren, bijvoorbeeld bij een mee-aanvraag:
Onderstaand ziet u een programma­fragment waarin een inmelding voor bus 42 een mee-aanvraag geeft naar bus 41 en bus 43:

A[fc41] = IH[h41bus] || IH[h42bus];
IH[h42bus] = SD[dsi42bus];
A[fc42] |= IH[h42bus];
A[fc43] |= IH[h43bus] || IH[h42bus];

De mee-aanvraag voor fc43 zal direct komen, maar fc41 zal nog een machineslag moeten wachten.

Complexere volgordeproblemen
Op zich hoeft het boven­geschetste volgorde­probleem geen probleem te zijn, maar wanneer de CCOL-programmeur er van uit zou gaan dat dit wél tegelijkertijd optreedt, gaat het mis.

Bijvoorbeeld:
De wens is om bij een businmelding een inmeldvertraging te laten starten. Gedurende de inmeldvertraging mag fc48 NIET worden overgeslagen (gebruik daarvoor de PP: PrivilegePeriode). Echter de aanvraag voor fc48 mag pas worden ingediend als de inmeldvertraging is afgelopen.
Dit zou als volgt kunnen zijn geprogrammeerd:

IT[t48inmeldvertr] = SD[dsi48bus];  /* start inmeldvertraging bij eerste bus in traject (anders RT) */
IH[h48pp] = (SD[dsi48bus] && ST[t48inmeldvertr]) ? (TRUE) : (IH[h48pp] && R[fc48]); /* hulpwaarde overslag */
PP[fc48] = H[h48pp];                /* tegenhouden overslag */
A[fc48] |= EH[h48pp];               /* aanvraag na inmeldvertraging */

In het bovenstaande voorbeeld gaat veel mis door het beruchte volgordeprobleem:
• In de eerste regel wordt bij de eerste businmelding een timer gestart. Tot zover gaat het nog goed;
• Maar in de tweede regel wordt er van uitgegaan dat de ST van de timer gelijktijdig met de SD van de detectielus optreedt, en dat is NIET zo!
• Hierdoor wordt de IH nooit geset, en zal dus ook in de derde regel nooit de PP worden geset: de fasecyclus kan dus tóch worden overgeslagen;
• Als klap op de vuurpijl zal in de laatste regel de aanvraag nooit worden ingediend, doordat de hulpwaarde nooit opkomt en dus ook nooit afvalt, en daardoor nooit de EH komt, en daardoor nooit de A[fc48] komt.

Het volgordeprobleem als nieuwe mogelijkheid
De typische eigenschappen van het volgordeprobleem kunnen ook worden gebruikt (of “misbruikt”?) om het programmaverloop naar de hand te zetten. De vraag blijft wel of dit ‘netjes programmeren’ is:
Kan een ander het begrijpen. En kunt u het zélf over twee jaar ook nog begrijpen?

Ketenreacties
Wanneer fasecycli reageren op reacties van gebeurtenissen, dan creëert elke reactie een vertraging van een machine­slag (systeem­ronde). Bij sommige verkeers­regel­automaten is deze systeem­ronde beperkt tot 0,1 seconde. Dat lijkt weinig, maar speelt beslist een rol wanneer er complexe software en/of hogere rij­snelheden in het spel zijn. Een verschijn­bord (bijvoorbeeld bij ODYSA of een inter­actieve weg) moet bij elke voertuig­passage een bood­schap tonen. Wanneer keurig wordt berekend op welke afstand van de detectie­lussen het verschijn­bord moet komen te staan, dan kan de lengte van een keten­reactie in de software het verschil maken tussen net wél en net níet goed werken!

Stel dat er een reactie-op-een-reactie-op-een-reactie… plaats heeft, dan betekent elke tussen­stap een vertraging van 0,1 seconde. Met enige complexiteit van uw applicatie­programma betekent dit al gauw 5 stappen in de keten (en daaraan is niets overdreven), wat neerkomt op een halve seconde vertraging. In die halve seconde zijn voer­tuigen op provin­ciale wegen al weer ruim tien meter verder… en dan licht uw verschijn­bord pas op: voor de auto­mobilisten net te laat om het goed te kunnen lezen en te inter­preteren. Daar had niemand op gerekend toen de lussen werden geslepen!
Het volgorde­probleem kan dus grote gevolgen hebben!


Index van CCOL-onderwerpen


Reageer op dit bericht