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); }
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; }
int rfx_start() { PsmPartition ionwm = getIonwm(); Sdr sdr = getIonsdr(); IonVdb *vdb = getIonVdb(); Object iondbObj; IonDB iondb; Object elt; iondbObj = getIonDbObject(); CHKERR(sdr_begin_xn(sdr)); /* To lock memory. */ sdr_read(sdr, (char *) &iondb, iondbObj, sizeof(IonDB)); /* Destroy and re-create volatile contact and range * databases. This prevents contact/range duplication * as a result of adds before starting ION. */ sm_rbt_destroy(ionwm, vdb->contactIndex, rfx_erase_data, NULL); sm_rbt_destroy(ionwm, vdb->rangeIndex, rfx_erase_data, NULL); vdb->contactIndex = sm_rbt_create(ionwm); vdb->rangeIndex = sm_rbt_create(ionwm); /* Load range index for all asserted ranges. In so * doing, load the nodes for which ranges are known * and load events for all predicted changes in range. */ for (elt = sdr_list_first(sdr, iondb.ranges); elt; elt = sdr_list_next(sdr, elt)) { if (loadRange(elt) < 0) { putErrmsg("Can't load range.", NULL); sdr_exit_xn(sdr); return -1; } } /* Load contact index for all contacts. In so doing, * load the nodes for which contacts are planned (as * necessary) and load events for all planned changes * in data rate affecting the local node. */ iondbObj = getIonDbObject(); sdr_read(sdr, (char *) &iondb, iondbObj, sizeof(IonDB)); for (elt = sdr_list_first(sdr, iondb.contacts); elt; elt = sdr_list_next(sdr, elt)) { if (loadContact(elt) < 0) { putErrmsg("Can't load contact.", NULL); sdr_exit_xn(sdr); return -1; } } /* Start the rfx clock if necessary. */ /* if (vdb->clockPid == ERROR || sm_TaskExists(vdb->clockPid) == 0) { vdb->clockPid = pseudoshell("rfxclock"); } */ sdr_exit_xn(sdr); /* Unlock memory. */ return 0; }
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; }