diff --git a/src/claims.c b/src/claims.c new file mode 100644 index 0000000..62a387a --- /dev/null +++ b/src/claims.c @@ -0,0 +1,193 @@ +#include +#include "termmaps.h" +#include "runs.h" +#include "error.h" + +#define MATCH_NONE 0 +#define MATCH_ORDER 1 +#define MATCH_REVERSE 2 + +#define LABEL_GOOD -3 +#define LABEL_TODO -2 + +/* + * Validity checks for claims + */ + +//! Check complete message match +/** + *@returns any of the MATCH_ signals + */ +int +events_match (const System sys, const int i, const int j) +{ + Roledef rdi, rdj; + + rdi = sys->traceEvent[i]; + rdj = sys->traceEvent[j]; + if (rdi->message == rdj->message && rdi->from == rdj->from && + rdi->to == rdj->to && rdi->label == rdj->label && + !(rdi->internal || rdj->internal)) + { + if (rdi->type == SEND && rdj->type == READ) + { + if (itype == READ && rdj->type == SEND) + { + if (i>j) + return MATCH_ORDER; + else + return MATCH_REVERSE; + } + } + return MATCH_NONE; +} + +//! nisynch generalization +/** + * f maps the involved roles to run identifiers. + * g maps all labels in prec to the event indices for things already found, + * or to LABEL_TODO for things not found yet but in prec, and LABEL_GOOD for well linked messages (and that have thus defined a runid for the corresponding role). + * All values not in prec map to -1. + */ +int +oki_nisynch (const System sys, const int i, const Termmap f, const Termmap g) +{ + // Check for completed trace + if (i == -1) + { + // Are all labels well linked? + Termmap gscan; + + gscan = g; + while (gscan != NULL) + { + if (gscan->result != LABEL_GOOD) + return 0; + gscan = gscan->next; + } + return 1; + } + else + { + Roledef rd; + int rid; + + rd = sys->traceEvent[i]; + rid = sys->traceRun[i]; + /* + * Simple case: internal event or claim + */ + if (rd->type == CLAIM || rd->internal) + { + return oki_nisynch (sys,i-1,f,g); + } + else + { + /* + * More difficult cases: send and read + */ + if (rd->type == READ) + { + /* + * Read is only relevant for already involved runs, and labels in prec + */ + Termmap fscan; + + fscan = f; + while (fscan != NULL) + { + if (fscan->result == rid) + { + // Involved, but is it a prec label? + if (termmapGet (g, rd->label) == LABEL_TODO) + { + Termmap gbuf; + int result; + + gbuf = termmapDuplicate (g); + gbuf = termmapSet (gbuf, rd->label, i); + result = oki_nisynch (sys,i-1,f,gbuf); + termmapDelete (gbuf); + return result; + } + } + fscan = fscan->next; + } + // Apparently not involved + return oki_nisynch (sys,i-1,f,g); + } + if (rd->type == SEND) + { + // Scan whether we were waiting for it or not + int result; + int rid2; + Term rolename; + Termmap gscan; + + rolename = sys->runs[rid].role->nameterm; + rid2 = termmapGet (f, rolename); + result = oki_nisynch (sys, i-1, f, g); + // Assume that this run is not yet involved + gscan = g; + while (gscan != NULL) + { + // Ordered match needed + if (gscan->result > -1 && + events_match (sys, gscan->result, i) == 1) + { + // Events match: but is the run a good candidate? + if (rid2 == -1 || rid2 == rid) + { + Termmap fbuf, gbuf; + + /** + *@todo Optimization can be done when rid2 == rid, no copy of f needs to be made. + */ + fbuf = termmapDuplicate (f); + fbuf = termmapSet (fbuf, rolename, rid); + gbuf = termmapDuplicate (g); + gbuf = termmapSet (gbuf, rd->label, -3); + result = oki_nisynch (sys, i-1, fbuf, gbuf); + termmapDelete (gbuf); + termmapDelete (fbuf); + } + } + gscan = gscan->next; + } + return result; + } + /* + * Exception: no send, no read, what is it? + */ + error ("Unrecognized event type in claim scanner at %i.", i); + } + } +} + +/* + * Real checks + */ + +//! Check validity of ni-synch claim at event i. +int +check_claim_nisynch (const System sys, const int i) +{ + int result; + int rid; + Termmap f,g; + + rid = sys->traceRun[i]; + f = termmapSet (NULL, sys->runs[rid].role->nameterm, rid); + /** + *@todo g should map all labels in prec to LABEL_TODO + */ + result = oki_nisynch(sys, i, f, NULL); + termmapDelete (f); + return result; +} + diff --git a/src/claims.h b/src/claims.h new file mode 100644 index 0000000..3fe7103 --- /dev/null +++ b/src/claims.h @@ -0,0 +1,6 @@ +#ifndef CLAIMS +#define CLAIMS + +int check_claim_nisynch (const System sys, const int i); + +#endif