static void logEvent(PsmPartition trace, int opType, unsigned long addr, int objectSize, char *msg, char *fileName, int lineNbr, PsmAddress *eltp) { PsmAddress traceHeaderAddress; TraceHeader *trh; PsmAddress itemAddr; TraceItem *item; int buflen; PsmAddress elt; if (eltp) { *eltp = 0; } traceHeaderAddress = psm_get_root(trace); trh = (TraceHeader *) psp(trace, traceHeaderAddress); if (trh == NULL) return; itemAddr = psm_zalloc(trace, sizeof(TraceItem)); if (itemAddr == 0) { discardEvent(trace); return; } item = (TraceItem *) psp(trace, itemAddr); memset((char *) item, 0, sizeof(TraceItem)); if (msg) { buflen = strlen(msg) + 1; item->msg = psm_zalloc(trace, buflen); if (item->msg == 0) { discardEvent(trace); return; } istrcpy((char *) psp(trace, item->msg), msg, buflen); } item->taskId = sm_TaskIdSelf(); item->fileName = findFileName(trace, trh, fileName); if (item->fileName == 0) { return; /* Events are being discarded. */ } item->lineNbr = lineNbr; trh->opCount++; item->opNbr = trh->opCount; item->opType = opType; item->objectAddress = addr; item->objectSize = objectSize; elt = sm_list_insert_last(trace, trh->log, itemAddr); if (elt == 0) { discardEvent(trace); return; } if (eltp) { *eltp = elt; } }
static PsmAddress insertCXref(IonCXref *cxref) { PsmPartition ionwm = getIonwm(); IonVdb *vdb = getIonVdb(); IonNode *node; PsmAddress nextElt; PsmAddress cxaddr; Object iondbObj; IonDB iondb; PsmAddress cxelt; PsmAddress addr; IonEvent *event; time_t currentTime = getUTCTime(); /* Load the affected nodes. */ node = findNode(vdb, cxref->toNode, &nextElt); if (node == NULL) { node = addNode(vdb, cxref->toNode); if (node == NULL) { return 0; } } node = findNode(vdb, cxref->fromNode, &nextElt); if (node == NULL) { node = addNode(vdb, cxref->fromNode); if (node == NULL) { return 0; } } /* Construct the contact index entry. */ cxaddr = psm_zalloc(ionwm, sizeof(IonCXref)); if (cxaddr == 0) { return 0; } /* Compute times of relevant events. */ iondbObj = getIonDbObject(); sdr_read(getIonsdr(), (char *) &iondb, iondbObj, sizeof(IonDB)); if (cxref->fromNode == getOwnNodeNbr()) { /* Be a little slow to start transmission, and * a little quick to stop, to ensure that * segments arrive only when neighbor is * expecting them. */ cxref->startXmit = cxref->fromTime + iondb.maxClockError; cxref->stopXmit = cxref->toTime - iondb.maxClockError; } if (cxref->toNode == getOwnNodeNbr()) { /* Be a little slow to resume timers, and a * little quick to suspend them, to minimize the * chance of premature timeout. */ cxref->startFire = cxref->fromTime + iondb.maxClockError; cxref->stopFire = cxref->toTime - iondb.maxClockError; } else /* Not a transmission to the local node. */ { cxref->purgeTime = cxref->toTime; } memcpy((char *) psp(ionwm, cxaddr), (char *) cxref, sizeof(IonCXref)); cxelt = sm_rbt_insert(ionwm, vdb->contactIndex, cxaddr, rfx_order_contacts, cxref); if (cxelt == 0) { psm_free(ionwm, cxaddr); return 0; } /* Insert relevant timeline events. */ if (cxref->startXmit) { addr = psm_zalloc(ionwm, sizeof(IonEvent)); if (addr == 0) { return 0; } event = (IonEvent *) psp(ionwm, addr); event->time = cxref->startXmit; event->type = IonStartXmit; event->ref = cxaddr; if (sm_rbt_insert(ionwm, vdb->timeline, addr, rfx_order_events, event) == 0) { psm_free(ionwm, addr); return 0; } } if (cxref->stopXmit) { addr = psm_zalloc(ionwm, sizeof(IonEvent)); if (addr == 0) { return 0; } event = (IonEvent *) psp(ionwm, addr); event->time = cxref->stopXmit; event->type = IonStopXmit; event->ref = cxaddr; if (sm_rbt_insert(ionwm, vdb->timeline, addr, rfx_order_events, event) == 0) { psm_free(ionwm, addr); return 0; } } if (cxref->startFire) { addr = psm_zalloc(ionwm, sizeof(IonEvent)); if (addr == 0) { return 0; } event = (IonEvent *) psp(ionwm, addr); event->time = cxref->startFire; event->type = IonStartFire; event->ref = cxaddr; if (sm_rbt_insert(ionwm, vdb->timeline, addr, rfx_order_events, event) == 0) { psm_free(ionwm, addr); return 0; } } if (cxref->stopFire) { addr = psm_zalloc(ionwm, sizeof(IonEvent)); if (addr == 0) { return 0; } event = (IonEvent *) psp(ionwm, addr); event->time = cxref->stopFire; event->type = IonStopFire; event->ref = cxaddr; if (sm_rbt_insert(ionwm, vdb->timeline, addr, rfx_order_events, event) == 0) { psm_free(ionwm, addr); return 0; } } if (cxref->purgeTime) { addr = psm_zalloc(ionwm, sizeof(IonEvent)); if (addr == 0) { return 0; } event = (IonEvent *) psp(ionwm, addr); event->time = cxref->purgeTime; event->type = IonPurgeContact; event->ref = cxaddr; if (sm_rbt_insert(ionwm, vdb->timeline, addr, rfx_order_events, event) == 0) { psm_free(ionwm, addr); return 0; } } if (cxref->toTime > currentTime) /* Affects routes. */ { vdb->lastEditTime = currentTime; } return cxaddr; }
int addEmbargo(IonNode *node, uvast neighborNodeNbr) { PsmPartition ionwm = getIonwm(); PsmAddress nextElt; PsmAddress elt; Embargo *embargo; PsmAddress addr; /* Find insertion point in embargoes list. */ CHKERR(node); nextElt = 0; for (elt = sm_list_first(ionwm, node->embargoes); elt; elt = sm_list_next(ionwm, elt)) { embargo = (Embargo *) psp(ionwm, sm_list_data(ionwm, elt)); CHKERR(embargo); if (embargo->nodeNbr < neighborNodeNbr) { continue; } if (embargo->nodeNbr > neighborNodeNbr) { nextElt = elt; break; /* Have found insertion point. */ } return 0; /* Embargo has already been added. */ } addr = psm_zalloc(ionwm, sizeof(Embargo)); if (addr == 0) { putErrmsg("Can't add embargo.", NULL); return -1; } if (nextElt) { elt = sm_list_insert_before(ionwm, nextElt, addr); } else { elt = sm_list_insert_last(ionwm, node->embargoes, addr); } if (elt == 0) { psm_free(ionwm, addr); putErrmsg("Can't add embargo.", NULL); return -1; } embargo = (Embargo *) psp(ionwm, addr); CHKERR(embargo); embargo->nodeNbr = neighborNodeNbr; embargo->probeIsDue = 0; postProbeEvent(node, embargo); /* Initial probe event. */ return 0; }
static PsmAddress insertRXref(IonRXref *rxref) { PsmPartition ionwm = getIonwm(); IonVdb *vdb = getIonVdb(); IonNode *node; PsmAddress nextElt; IonRXref arg; PsmAddress rxaddr; PsmAddress rxelt; PsmAddress addr; IonEvent *event; PsmAddress rxaddr2; IonRXref *rxref2; time_t currentTime = getUTCTime(); /* Load the affected nodes. */ node = findNode(vdb, rxref->toNode, &nextElt); if (node == NULL) { node = addNode(vdb, rxref->toNode); if (node == NULL) { return 0; } } node = findNode(vdb, rxref->fromNode, &nextElt); if (node == NULL) { node = addNode(vdb, rxref->fromNode); if (node == NULL) { return 0; } } /* Construct the range index entry. */ rxaddr = psm_zalloc(ionwm, sizeof(IonRXref)); if (rxaddr == 0) { return 0; } memcpy((char *) psp(ionwm, rxaddr), (char *) rxref, sizeof(IonRXref)); rxelt = sm_rbt_insert(ionwm, vdb->rangeIndex, rxaddr, rfx_order_ranges, rxref); if (rxelt == 0) { psm_free(ionwm, rxaddr); return 0; } /* Insert relevant asserted timeline events. */ addr = psm_zalloc(ionwm, sizeof(IonEvent)); if (addr == 0) { return 0; } event = (IonEvent *) psp(ionwm, addr); event->time = rxref->fromTime; event->type = IonStartAssertedRange; event->ref = rxaddr; if (sm_rbt_insert(ionwm, vdb->timeline, addr, rfx_order_events, event) == 0) { return 0; } addr = psm_zalloc(ionwm, sizeof(IonEvent)); if (addr == 0) { return 0; } event = (IonEvent *) psp(ionwm, addr); event->time = rxref->toTime; event->type = IonStopAssertedRange; event->ref = rxaddr; if (sm_rbt_insert(ionwm, vdb->timeline, addr, rfx_order_events, event) == 0) { return 0; } if (rxref->toTime > currentTime) /* Affects routes. */ { vdb->lastEditTime = currentTime; } if (rxref->fromNode > rxref->toNode) { /* This is a non-canonical range assertion, * indicating an override of the normal * symmetry in the owlt between nodes. The * reverse range assertion does *not* hold. */ return rxaddr; } /* This is a canonical range assertion, so we may need * to insert the imputed (symmetrical) reverse range * assertion as well. Is the reverse range already * asserted? */ arg.fromNode = rxref->toNode; arg.toNode = rxref->fromNode; arg.fromTime = rxref->fromTime; rxelt = sm_rbt_search(ionwm, vdb->rangeIndex, rfx_order_ranges, &arg, &nextElt); if (rxelt) /* Asserted range exists; we're done. */ { return rxaddr; } /* Reverse range is not asserted, so it must be imputed. * * First, load index entry for the imputed range. */ rxaddr2 = psm_zalloc(ionwm, sizeof(IonRXref)); if (rxaddr2 == 0) { return 0; } rxref2 = (IonRXref *) psp(ionwm, rxaddr2); rxref2->fromNode = rxref->toNode; /* Reversed. */ rxref2->toNode = rxref->fromNode; /* Reversed. */ rxref2->fromTime = rxref->fromTime; rxref2->toTime = rxref->toTime; rxref2->owlt = rxref->owlt; rxref2->rangeElt = 0; /* Indicates "imputed". */ memcpy((char *) psp(ionwm, rxaddr2), (char *) rxref2, sizeof(IonRXref)); rxelt = sm_rbt_insert(ionwm, vdb->rangeIndex, rxaddr2, rfx_order_ranges, rxref2); if (rxelt == 0) { psm_free(ionwm, rxaddr2); return 0; } /* Then insert relevant imputed timeline events. */ addr = psm_zalloc(ionwm, sizeof(IonEvent)); if (addr == 0) { return 0; } event = (IonEvent *) psp(ionwm, addr); event->time = rxref->fromTime; event->type = IonStartImputedRange; event->ref = rxaddr2; if (sm_rbt_insert(ionwm, vdb->timeline, addr, rfx_order_events, event) == 0) { psm_free(ionwm, addr); return 0; } addr = psm_zalloc(ionwm, sizeof(IonEvent)); if (addr == 0) { return 0; } event = (IonEvent *) psp(ionwm, addr); event->time = rxref->toTime; event->type = IonStopImputedRange; event->ref = rxaddr2; if (sm_rbt_insert(ionwm, vdb->timeline, addr, rfx_order_events, event) == 0) { psm_free(ionwm, addr); return 0; } return rxaddr; }
IonVdb * createIonVdb(char * ionvdbName) { IonVdb *vdb = NULL; PsmAddress vdbAddress; PsmAddress elt; Sdr sdr; PsmPartition ionwm; IonDB iondb; char * name = ionvdbName; /* Attaching to volatile database. */ ionwm = getIonwm(); if (psm_locate(ionwm, name, &vdbAddress, &elt) < 0) { putErrmsg("Failed searching for vdb.", name); return NULL; } if (elt) { vdb = (IonVdb *) psp(ionwm, vdbAddress); } if (vdb != NULL) return vdb; /* ION volatile database doesn't exist yet. */ sdr = getIonsdr(); CHKNULL(sdr_begin_xn(sdr)); /* To lock memory. */ vdbAddress = psm_zalloc(ionwm, sizeof(IonVdb)); if (vdbAddress == 0) { sdr_exit_xn(sdr); putErrmsg("No space for volatile database.", name); return NULL; } vdb = (IonVdb *) psp(ionwm, vdbAddress); memset((char *) vdb, 0, sizeof(IonVdb)); if ((vdb->nodes = sm_rbt_create(ionwm)) == 0 || (vdb->neighbors = sm_rbt_create(ionwm)) == 0 || (vdb->contactIndex = sm_rbt_create(ionwm)) == 0 || (vdb->rangeIndex = sm_rbt_create(ionwm)) == 0 || (vdb->timeline = sm_rbt_create(ionwm)) == 0 || (vdb->probes = sm_list_create(ionwm)) == 0 || (vdb->requisitions[0] = sm_list_create(ionwm)) == 0 || (vdb->requisitions[1] = sm_list_create(ionwm)) == 0 || psm_catlg(ionwm, name, vdbAddress) < 0) { sdr_exit_xn(sdr); putErrmsg("Can't initialize volatile database.", name); return NULL; } vdb->clockPid = ERROR; /* None yet. */ sdr_read(sdr, (char *) &iondb, getIonDbObject(), sizeof(IonDB)); vdb->deltaFromUTC = iondb.deltaFromUTC; sdr_exit_xn(sdr); /* Unlock memory. */ //fprintf(stderr, "ionVdb created: %d\n", getOwnNodeNbr()); return vdb; }
static IonVdb *_ionvdb(char **name) { static IonVdb *vdb = NULL; PsmAddress vdbAddress; PsmAddress elt; Sdr sdr; PsmPartition ionwm; IonDB iondb; if (name) { if (*name == NULL) /* Terminating. */ { vdb = NULL; return vdb; } /* Attaching to volatile database. */ ionwm = _ionwm(NULL); if (psm_locate(ionwm, *name, &vdbAddress, &elt) < 0) { putErrmsg("Failed searching for vdb.", *name); return NULL; } if (elt) { vdb = (IonVdb *) psp(ionwm, vdbAddress); return vdb; } /* ION volatile database doesn't exist yet. */ sdr = _ionsdr(NULL); CHKNULL(sdr_begin_xn(sdr)); /* To lock memory. */ vdbAddress = psm_zalloc(ionwm, sizeof(IonVdb)); if (vdbAddress == 0) { sdr_exit_xn(sdr); putErrmsg("No space for volatile database.", *name); return NULL; } vdb = (IonVdb *) psp(ionwm, vdbAddress); memset((char *) vdb, 0, sizeof(IonVdb)); vdb->zcoSemaphore = sm_SemCreate(SM_NO_KEY, SM_SEM_FIFO); if (vdb->zcoSemaphore == SM_SEM_NONE) { sdr_exit_xn(sdr); putErrmsg("Can't initialize volatile database.", *name); return NULL; } sm_SemTake(vdb->zcoSemaphore); /* Lock it. */ if ((vdb->nodes = sm_rbt_create(ionwm)) == 0 || (vdb->neighbors = sm_rbt_create(ionwm)) == 0 || (vdb->contactIndex = sm_rbt_create(ionwm)) == 0 || (vdb->rangeIndex = sm_rbt_create(ionwm)) == 0 || (vdb->timeline = sm_rbt_create(ionwm)) == 0 || (vdb->probes = sm_list_create(ionwm)) == 0 || psm_catlg(ionwm, *name, vdbAddress) < 0) { sdr_exit_xn(sdr); putErrmsg("Can't initialize volatile database.", *name); return NULL; } vdb->clockPid = ERROR; /* None yet. */ sdr_read(sdr, (char *) &iondb, _iondbObject(NULL), sizeof(IonDB)); vdb->deltaFromUTC = iondb.deltaFromUTC; sdr_exit_xn(sdr); /* Unlock memory. */ } return vdb; }