static void destroyIonNode(PsmPartition partition, PsmAddress eltData, void *argument) { IonNode *node = (IonNode *) psp(partition, eltData); sm_list_destroy(partition, node->snubs, rfx_erase_data, NULL); psm_free(partition, eltData); }
void rfx_stop() { PsmPartition ionwm = getIonwm(); IonVdb *vdb = getIonVdb(); int i; PsmAddress elt; PsmAddress nextElt; PsmAddress addr; Requisition *req; /* Safely shut down the ZCO flow control system. */ for (i = 0; i < 1; i++) { for (elt = sm_list_first(ionwm, vdb->requisitions[i]); elt; elt = nextElt) { nextElt = sm_list_next(ionwm, elt); addr = sm_list_data(ionwm, elt); req = (Requisition *) psp(ionwm, addr); sm_SemEnd(req->semaphore); psm_free(ionwm, addr); sm_list_delete(ionwm, elt, NULL, NULL); } } //zco_unregister_callback(); /* Stop the rfx clock if necessary. */ /* if (vdb->clockPid != ERROR) { sm_TaskKill(vdb->clockPid, SIGTERM); while (sm_TaskExists(vdb->clockPid)) { microsnooze(100000); } vdb->clockPid = ERROR; } */ /* Wipe out all red-black trees involved in routing, * for reconstruction on restart. */ sm_rbt_destroy(ionwm, vdb->contactIndex, rfx_erase_data, NULL); sm_rbt_destroy(ionwm, vdb->rangeIndex, rfx_erase_data, NULL); sm_rbt_destroy(ionwm, vdb->timeline, rfx_erase_data, NULL); vdb->contactIndex = sm_rbt_create(ionwm); vdb->rangeIndex = sm_rbt_create(ionwm); vdb->timeline = sm_rbt_create(ionwm); }
static void dropVdb(PsmPartition wm, PsmAddress vdbAddress) { IonVdb *vdb; int i; PsmAddress elt; PsmAddress nextElt; PsmAddress addr; Requisition *req; vdb = (IonVdb *) psp(wm, vdbAddress); /* Time-ordered list of probes can simply be destroyed. */ sm_list_destroy(wm, vdb->probes, rfx_erase_data, NULL); /* Three of the red-black tables in the Vdb are * emptied and recreated by rfx_stop(). Destroy them. */ sm_rbt_destroy(wm, vdb->contactIndex, NULL, NULL); sm_rbt_destroy(wm, vdb->rangeIndex, NULL, NULL); sm_rbt_destroy(wm, vdb->timeline, NULL, NULL); /* cgr_stop clears all routing objects, so nodes and * neighbors themselves can now be deleted. */ sm_rbt_destroy(wm, vdb->nodes, destroyIonNode, NULL); sm_rbt_destroy(wm, vdb->neighbors, rfx_erase_data, NULL); /* Safely shut down the ZCO flow control system. */ for (i = 0; i < 1; i++) { for (elt = sm_list_first(wm, vdb->requisitions[i]); elt; elt = nextElt) { nextElt = sm_list_next(wm, elt); addr = sm_list_data(wm, elt); req = (Requisition *) psp(wm, addr); sm_SemEnd(req->semaphore); psm_free(wm, addr); sm_list_delete(wm, elt, NULL, NULL); } } //zco_unregister_callback(); }
IonNeighbor *addNeighbor(IonVdb *ionvdb, uvast nodeNbr) { PsmPartition ionwm = getIonwm(); IonNode *node; PsmAddress nextElt; PsmAddress addr; PsmAddress elt; IonNeighbor *neighbor; node = findNode(ionvdb, nodeNbr, &nextElt); if (node == NULL) { node = addNode(ionvdb, nodeNbr); if (node == NULL) { putErrmsg("Can't add neighboring node.", NULL); return NULL; } } addr = psm_zalloc(ionwm, sizeof(IonNeighbor)); if (addr == 0) { putErrmsg("Can't add neighbor.", NULL); return NULL; } neighbor = (IonNeighbor *) psp(ionwm, addr); CHKNULL(neighbor); memset((char *) neighbor, 0, sizeof(IonNeighbor)); neighbor->nodeNbr = nodeNbr; neighbor->node = psa(ionwm, node); elt = sm_rbt_insert(ionwm, ionvdb->neighbors, addr, rfx_order_neighbors, neighbor); if (elt == 0) { psm_free(ionwm, addr); putErrmsg("Can't add neighbor.", NULL); return NULL; } return neighbor; }
static void ionDropVdb(char * vdbName) { PsmPartition wm = getIonwm(); char *ionvdbName = vdbName; PsmAddress vdbAddress; PsmAddress elt; if (psm_locate(wm, ionvdbName, &vdbAddress, &elt) < 0) { putErrmsg("Failed searching for vdb.", NULL); return; } if (elt) { dropVdb(wm, vdbAddress); /* Destroy Vdb. */ if (psm_uncatlg(wm, ionvdbName) < 0) { putErrmsg("Failed uncataloging vdb.", NULL); } psm_free(wm, vdbAddress); } }
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; }
void rfx_erase_data(PsmPartition partition, PsmAddress nodeData, void *argument) { psm_free(partition, nodeData); }
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; }
int main(int argc, char **argv) #endif { char *wmspace; int wmid; PsmPartition wm = NULL; PsmMgtOutcome outcome; PsmAddress testlist; sm_SemId semaphore; int cycleNbr = 1; char fileName[256]; int outputFile; PsmAddress lineListElt; PsmAddress lineAddress; char *line; if (sm_ipc_init() < 0) { return 0; } if (sm_ShmAttach(0x1108, 10000000, &wmspace, &wmid) < 0) { PERROR("can't attach to shared memory"); return 0; } if (psm_manage(wmspace, 10000000, "file2sm", &wm, &outcome) < 0 || outcome == Refused) { PUTS("can't manage shared memory"); return 0; } testlist = psm_get_root(wm); if (testlist == 0) { testlist = sm_list_create(wm); if (testlist == 0) { PUTS("can't create shared memory list"); return 0; } psm_set_root(wm, testlist); } semaphore = sm_SemCreate(0x1101, SM_SEM_FIFO); if (semaphore < 0) { PUTS("can't create semaphore"); return 0; } PUTMEMO("Working on cycle", utoa(cycleNbr)); isprintf(fileName, sizeof fileName, "file_copy_%d", cycleNbr); outputFile = iopen(fileName, O_WRONLY | O_APPEND, 0666); if (outputFile < 0) { PERROR("can't open output file"); return 0; } while (1) { while (sm_list_length(wm, testlist) == 0) { sm_SemTake(semaphore); /* Wait for line. */ } lineListElt = sm_list_first(wm, testlist); lineAddress = sm_list_data(wm, lineListElt); line = psp(wm, lineAddress); /* Process text of line. */ if (strcmp(line, "*** End of the file ***\n") == 0) { /* Close file, open next one. */ close(outputFile); cycleNbr++; PUTMEMO("Working on cycle", utoa(cycleNbr)); isprintf(fileName, sizeof fileName, "file_copy_%d", cycleNbr); outputFile = iopen(fileName, O_WRONLY | O_APPEND, 0666); if (outputFile < 0) { PERROR("Can't open output file"); return 0; } } else /* Just write line to output file. */ { if (iputs(outputFile, line) < 0) { close(outputFile); PERROR("Can't write to output file"); return 0; } } /* Delete line from shared memory list. */ psm_free(wm, lineAddress); CHKZERO(sm_list_delete(wm, lineListElt, (SmListDeleteFn) NULL, NULL) == 0); } }