static void applyRateControl(Sdr sdr) { BpVdb *vdb = getBpVdb(); PsmPartition ionwm = getIonwm(); Throttle *throttle; PsmAddress elt; VInduct *induct; VOutduct *outduct; long capacityLimit; sdr_begin_xn(sdr); /* Just to lock memory. */ /* Recalculate limit on local bundle generation. */ manageProductionThrottle(vdb); /* Enable some bundle acquisition. */ for (elt = sm_list_first(ionwm, vdb->inducts); elt; elt = sm_list_next(ionwm, elt)) { induct = (VInduct *) psp(ionwm, sm_list_data(ionwm, elt)); throttle = &(induct->acqThrottle); capacityLimit = throttle->nominalRate << 1; throttle->capacity += throttle->nominalRate; if (throttle->capacity > capacityLimit) { throttle->capacity = capacityLimit; } if (throttle->capacity > 0) { sm_SemGive(throttle->semaphore); } } /* Enable some bundle transmission. */ for (elt = sm_list_first(ionwm, vdb->outducts); elt; elt = sm_list_next(ionwm, elt)) { outduct = (VOutduct *) psp(ionwm, sm_list_data(ionwm, elt)); throttle = &(outduct->xmitThrottle); capacityLimit = throttle->nominalRate << 1; throttle->capacity += throttle->nominalRate; if (throttle->capacity > capacityLimit) { throttle->capacity = capacityLimit; } if (throttle->capacity > 0) { sm_SemGive(throttle->semaphore); } } sdr_exit_xn(sdr); /* Unlock memory. */ }
static void *timerMain(void *parm) { TimerParms *timer = (TimerParms *) parm; pthread_mutex_t mutex; pthread_cond_t cv; struct timeval workTime; struct timespec deadline; int result; memset((char *) &mutex, 0, sizeof mutex); if (pthread_mutex_init(&mutex, NULL)) { putSysErrmsg("can't start timer, mutex init failed", NULL); sm_SemGive(timer->semaphore); return NULL; } memset((char *) &cv, 0, sizeof cv); if (pthread_cond_init(&cv, NULL)) { putSysErrmsg("can't start timer, cond init failed", NULL); sm_SemGive(timer->semaphore); return NULL; } getCurrentTime(&workTime); deadline.tv_sec = workTime.tv_sec + timer->interval; deadline.tv_nsec = workTime.tv_usec * 1000; pthread_mutex_lock(&mutex); result = pthread_cond_timedwait(&cv, &mutex, &deadline); pthread_mutex_unlock(&mutex); pthread_mutex_destroy(&mutex); pthread_cond_destroy(&cv); if (result) { errno = result; if (errno != ETIMEDOUT) { putSysErrmsg("timer failure", NULL); sm_SemGive(timer->semaphore); return NULL; } } /* Timed out; must wake up the main thread. */ timer->interval = 0; /* Indicate genuine timeout. */ sm_SemGive(timer->semaphore); return NULL; }
void bp_interrupt(BpSAP sap) { /* Give semaphore, simulating reception notice. */ if (sap != NULL && sap->recvSemaphore != SM_SEM_NONE) { sm_SemGive(sap->recvSemaphore); } }
static void ionReleaseZcoSpace(IonVdb *vdb) { /* If there are any remaining claims then let the * next claimant in the queue (possibly this claimant, * now re-appended to semaphore's FIFO) take a shot. */ if (vdb->zcoClaims > 0) { oK(sm_SemGive(vdb->zcoSemaphore)); } }
static void unlockPartition(PartitionMap *map) { if (map->status == MANAGED && map->ownerTask == sm_TaskIdSelf() && pthread_equal(map->ownerThread, pthread_self())) { map->depth--; if (map->depth == 0) { map->ownerTask = -1; if (map->semaphore != -1) { sm_SemGive(map->semaphore); } } } }
static void ionOfferZcoSpace() { IonVdb *vdb = _ionvdb(NULL); if (vdb) { /* Give all tasks currently waiting for ZCO * space a shot at claiming the space that * has now been made available. */ vdb->zcoClaims += vdb->zcoClaimants; vdb->zcoClaimants = 0; if (vdb->zcoClaims > 0) { sm_SemGive(vdb->zcoSemaphore); } } }
static int manageLinks(Sdr sdr, time_t currentTime) { PsmPartition ionwm = getIonwm(); LtpVdb *ltpvdb = getLtpVdb(); IonVdb *ionvdb = getIonVdb(); PsmAddress elt; LtpVspan *vspan; Object obj; LtpSpan span; IonNeighbor *neighbor; PsmAddress nextElt; unsigned long priorXmitRate; sdr_begin_xn(sdr); for (elt = sm_list_first(ionwm, ltpvdb->spans); elt; elt = sm_list_next(ionwm, elt)) { vspan = (LtpVspan *) psp(ionwm, sm_list_data(ionwm, elt)); /* Finish aggregation as necessary. */ obj = sdr_list_data(sdr, vspan->spanElt); sdr_stage(sdr, (char *) &span, obj, sizeof(LtpSpan)); if (span.lengthOfBufferedBlock > 0) { span.ageOfBufferedBlock++; sdr_write(sdr, obj, (char *) &span, sizeof(LtpSpan)); if (span.ageOfBufferedBlock >= span.aggrTimeLimit) { sm_SemGive(vspan->bufFullSemaphore); } } /* Find Neighbor object encapsulating the current * known state of this LTP engine. */ neighbor = findNeighbor(ionvdb, vspan->engineId, &nextElt); if (neighbor == NULL) { neighbor = addNeighbor(ionvdb, vspan->engineId, nextElt); if (neighbor == NULL) { putErrmsg("Can't update span.", NULL); return -1; } } if (neighbor->xmitRate == 0) { if (vspan->localXmitRate > 0) { vspan->localXmitRate = 0; ltpStopXmit(vspan); } } else { if (vspan->localXmitRate == 0) { vspan->localXmitRate = neighbor->xmitRate; ltpStartXmit(vspan); } } if (neighbor->fireRate == 0) { if (vspan->remoteXmitRate > 0) { priorXmitRate = vspan->remoteXmitRate; vspan->remoteXmitRate = 0; if (ltpSuspendTimers(vspan, elt, currentTime, priorXmitRate)) { putErrmsg("Can't manage links.", NULL); return -1; } } } else { if (vspan->remoteXmitRate == 0) { vspan->remoteXmitRate = neighbor->fireRate; if (ltpResumeTimers(vspan, elt, currentTime, vspan->remoteXmitRate)) { putErrmsg("Can't manage links.", NULL); return -1; } } } if (neighbor->recvRate == 0) { vspan->receptionRate = 0; } else { vspan->receptionRate = neighbor->recvRate; } if (neighbor->owltInbound != vspan->owltInbound) { vspan->owltInbound = neighbor->owltInbound; } if (neighbor->owltOutbound != vspan->owltOutbound) { vspan->owltOutbound = neighbor->owltOutbound; } } if (sdr_end_xn(sdr) < 0) { putErrmsg("ltpclock failed managing links.", NULL); return -1; } return 0; }
static void unlockSmrbt(SmRbt *rbt) { sm_SemGive(rbt->lock); }
static int checkNodeListParms(IonParms *parms, char *wdName, uvast nodeNbr) { char *nodeListDir; sm_SemId nodeListMutex; char nodeListFileName[265]; int nodeListFile; int lineNbr = 0; int lineLen; char lineBuf[256]; uvast lineNodeNbr; int lineWmKey; char lineSdrName[MAX_SDR_NAME + 1]; char lineWdName[256]; int result; nodeListDir = getenv("ION_NODE_LIST_DIR"); if (nodeListDir == NULL) /* Single node on machine. */ { if (parms->wmKey == 0) { parms->wmKey = ION_DEFAULT_SM_KEY; } if (parms->wmKey != ION_DEFAULT_SM_KEY) { putErrmsg("Config parms wmKey != default.", itoa(ION_DEFAULT_SM_KEY)); return -1; } if (parms->sdrName[0] == '\0') { istrcpy(parms->sdrName, ION_DEFAULT_SDR_NAME, sizeof parms->sdrName); } if (strcmp(parms->sdrName, ION_DEFAULT_SDR_NAME) != 0) { putErrmsg("Config parms sdrName != default.", ION_DEFAULT_SDR_NAME); return -1; } return 0; } /* Configured for multi-node operation. */ nodeListMutex = sm_SemCreate(NODE_LIST_SEMKEY, SM_SEM_FIFO); if (nodeListMutex == SM_SEM_NONE || sm_SemUnwedge(nodeListMutex, 3) < 0 || sm_SemTake(nodeListMutex) < 0) { putErrmsg("Can't lock node list file.", NULL); return -1; } isprintf(nodeListFileName, sizeof nodeListFileName, "%.255s%cion_nodes", nodeListDir, ION_PATH_DELIMITER); if (nodeNbr == 0) /* Just attaching. */ { nodeListFile = iopen(nodeListFileName, O_RDONLY, 0); } else /* Initializing the node. */ { nodeListFile = iopen(nodeListFileName, O_RDWR | O_CREAT, 0666); } if (nodeListFile < 0) { sm_SemGive(nodeListMutex); putSysErrmsg("Can't open ion_nodes file", nodeListFileName); writeMemo("[?] Remove ION_NODE_LIST_DIR from env?"); return -1; } while (1) { if (igets(nodeListFile, lineBuf, sizeof lineBuf, &lineLen) == NULL) { if (lineLen < 0) { close(nodeListFile); sm_SemGive(nodeListMutex); putErrmsg("Failed reading ion_nodes file.", nodeListFileName); return -1; } break; /* End of file. */ } lineNbr++; if (sscanf(lineBuf, UVAST_FIELDSPEC " %d %31s %255s", &lineNodeNbr, &lineWmKey, lineSdrName, lineWdName) < 4) { close(nodeListFile); sm_SemGive(nodeListMutex); putErrmsg("Syntax error at line#", itoa(lineNbr)); writeMemoNote("[?] Repair ion_nodes file.", nodeListFileName); return -1; } if (lineNodeNbr == nodeNbr) /* Match. */ { /* lineNodeNbr can't be zero (we never * write such lines to the file), so this * must be matching non-zero node numbers. * So we are re-initializing this node. */ close(nodeListFile); if (strcmp(lineWdName, wdName) != 0) { sm_SemGive(nodeListMutex); putErrmsg("CWD conflict at line#", itoa(lineNbr)); writeMemoNote("[?] Repair ion_nodes file.", nodeListFileName); return -1; } if (parms->wmKey == 0) { parms->wmKey = lineWmKey; } if (parms->wmKey != lineWmKey) { sm_SemGive(nodeListMutex); putErrmsg("WmKey conflict at line#", itoa(lineNbr)); writeMemoNote("[?] Repair ion_nodes file.", nodeListFileName); return -1; } if (parms->sdrName[0] == '\0') { istrcpy(parms->sdrName, lineSdrName, sizeof parms->sdrName); } if (strcmp(parms->sdrName, lineSdrName) != 0) { sm_SemGive(nodeListMutex); putErrmsg("SdrName conflict at line#", itoa(lineNbr)); writeMemoNote("[?] Repair ion_nodes file.", nodeListFileName); return -1; } return 0; } /* lineNodeNbr does not match nodeNbr (which may * be zero). */ if (strcmp(lineWdName, wdName) == 0) /* Match. */ { close(nodeListFile); sm_SemGive(nodeListMutex); if (nodeNbr == 0) /* Attaching. */ { parms->wmKey = lineWmKey; istrcpy(parms->sdrName, lineSdrName, MAX_SDR_NAME + 1); return 0; } /* Reinitialization conflict. */ putErrmsg("NodeNbr conflict at line#", itoa(lineNbr)); writeMemoNote("[?] Repair ion_nodes file.", nodeListFileName); return -1; } /* Haven't found matching line yet. Continue. */ } /* No matching lines in file. */ if (nodeNbr == 0) /* Attaching to existing node. */ { close(nodeListFile); sm_SemGive(nodeListMutex); putErrmsg("No node has been initialized in this directory.", wdName); return -1; } /* Initializing, so append line to the nodes list file. */ if (parms->wmKey == 0) { parms->wmKey = ION_DEFAULT_SM_KEY; } if (parms->sdrName[0] == '\0') { istrcpy(parms->sdrName, ION_DEFAULT_SDR_NAME, sizeof parms->sdrName); } isprintf(lineBuf, sizeof lineBuf, UVAST_FIELDSPEC " %d %.31s %.255s\n", nodeNbr, parms->wmKey, parms->sdrName, wdName); result = iputs(nodeListFile, lineBuf); close(nodeListFile); sm_SemGive(nodeListMutex); if (result < 0) { putErrmsg("Failed writing to ion_nodes file.", NULL); return -1; } return 0; }
static void unlockSmlist(SmList *list) { sm_SemGive(list->lock); }