void hipaccStopTiming() { end_time = getMicroTime(); last_gpu_timing = (end_time - start_time) * 1.0e-3f; std::cerr << "<HIPACC:> Kernel timing: " << last_gpu_timing << "(ms)" << std::endl; }
/* ###### Check, if break has been detected ############################## */ bool breakDetected() { if((DetectedBreak) && (!PrintedBreak)) { if(!Quiet) { fprintf(stderr, "\x1b[0m\n*** Break *** Signal #%d\n\n", BreakSignal); } PrintedBreak = getMicroTime(); } return(DetectedBreak); }
/* ###### Create new session ############################################# */ struct Session* addSession(struct RSerPoolSocket* rserpoolSocket, const sctp_assoc_t assocID, const bool isIncoming, const unsigned char* poolHandle, const size_t poolHandleSize, struct TagItem* tags) { struct Session* session = (struct Session*)malloc(sizeof(struct Session)); if(session != NULL) { CHECK(rserpoolSocket->ConnectedSession == NULL); session->Tags = tagListDuplicate(tags); if(session->Tags == NULL) { free(session); return(NULL); } simpleRedBlackTreeNodeNew(&session->AssocIDNode); simpleRedBlackTreeNodeNew(&session->SessionIDNode); session->AssocID = assocID; session->IsIncoming = isIncoming; session->IsFailed = isIncoming ? false : true; if(poolHandleSize > 0) { CHECK(poolHandleSize <= MAX_POOLHANDLESIZE); poolHandleNew(&session->Handle, poolHandle, poolHandleSize); } else { session->Handle.Size = 0; } session->Cookie = NULL; session->CookieSize = 0; session->CookieEcho = NULL; session->CookieEchoSize = 0; session->StatusText[0] = 0x00; session->ConnectionTimeStamp = (isIncoming == true) ? getMicroTime() : 0; session->ConnectedPE = 0; session->ConnectTimeout = (unsigned long long)tagListGetData(tags, TAG_RspSession_ConnectTimeout, 5000000); session->HandleResolutionRetryDelay = (unsigned long long)tagListGetData(tags, TAG_RspSession_HandleResolutionRetryDelay, 250000); threadSafetyLock(&rserpoolSocket->Mutex); session->SessionID = identifierBitmapAllocateID(rserpoolSocket->SessionAllocationBitmap); if(session->SessionID >= 0) { threadSafetyLock(&rserpoolSocket->SessionSetMutex); sessionStorageAddSession(&rserpoolSocket->SessionSet, session); threadSafetyUnlock(&rserpoolSocket->SessionSetMutex); LOG_ACTION fprintf(stdlog, "Added %s session %u on RSerPool socket %d, socket %d\n", session->IsIncoming ? "incoming" : "outgoing", session->SessionID, rserpoolSocket->Descriptor, rserpoolSocket->Socket); LOG_END }
/* ###### Handler for SIGINT ############################################# */ void breakDetector(int signum) { BreakSignal = signum; DetectedBreak = true; #ifdef KILL_AFTER_TIMEOUT if(!PrintedKill) { const unsigned long long now = getMicroTime(); if(LastDetection == (unsigned long long)-1) { LastDetection = now; } else if(now - LastDetection >= 2000000) { PrintedKill = true; fprintf(stderr, "\x1b[0m\n*** Kill ***\n\n"); kill(MainThreadPID, SIGKILL); } } #endif }
/* ###### Get 32-bit random value ######################################## */ uint32_t random32() { #ifdef NDEBUG #warning Using OMNeT++ random generator instead of time-seeded one! const double value = uniform(0.0, (double)0xffffffff); return((uint32_t)rint(value)); #else uint32_t number; switch(RandomSource) { case RS_DEVICE: if(fread(&number, sizeof(number), 1, RandomDevice) == 1) { return(number); } RandomSource = RS_CLIB; case RS_CLIB: return(random()); case RS_TRY_DEVICE: RandomDevice = fopen("/dev/urandom", "r"); if(RandomDevice != NULL) { if(fread(&number, sizeof(number), 1, RandomDevice) == 1) { srandom(number); RandomSource = RS_DEVICE; return(number); } fclose(RandomDevice); } RandomSource = RS_CLIB; srandom((unsigned int)(getMicroTime() & (uint64_t)0xffffffff)); break; } return(random()); #endif }
API bool connectClientSocketAsync(Socket *s, int timeout) { if(s->connected) { logError("Cannot connect already connected socket %d", s->fd); return false; } if(s->type != SOCKET_CLIENT) { logError("Cannot asynchronously connect non-client socket"); return false; } struct addrinfo hints; struct addrinfo *server; int ret; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; // don't care if we use IPv4 or IPv6 to reach our destination hints.ai_socktype = SOCK_STREAM; // TCP stream sockets if((ret = getaddrinfo(s->host, s->port, &hints, &server)) != 0) { logError("Failed to look up address %s:%s: %s", s->host, s->port, gai_strerror(ret)); return false; } if((s->fd = socket(server->ai_family, server->ai_socktype, server->ai_protocol)) == -1) { logSystemError("Failed to create socket"); return false; } if(!setSocketNonBlocking(s->fd)) { logSystemError("Failed to set socket non-blocking"); closeSocket(s); return false; } logNotice("Asynchronously connecting client socket %d to %s:%s...", s->fd, s->host, s->port); if(connect(s->fd, server->ai_addr, server->ai_addrlen) < 0) { // try to connect socket #ifdef WIN32 if(WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK) { #else if(errno == EINPROGRESS) { #endif // free previous timer if present free(s->custom); AsyncConnectionTimer *timer = ALLOCATE_OBJECT(AsyncConnectionTimer); timer->creationTime = getMicroTime(); timer->timeout = timeout; s->custom = timer; g_queue_push_tail(connecting, s); // add to connecting list logInfo("Socket %d delayed connection, queueing...", s->fd); } else { #ifdef WIN32 char *error = g_win32_error_message(WSAGetLastError()); logError("Connection for socket %d failed: %s", s->fd, error); free(error); #else logSystemError("Connection for socket %d failed", s->fd); #endif closeSocket(s); freeaddrinfo(server); return false; } } else { logNotice("Direct response for asynchronous connection on socket %d", s->fd); s->connected = true; triggerEvent(s, "connected"); enableSocketPolling(s); } freeaddrinfo(server); return true; } API bool enableSocketPolling(Socket *socket) { if(isSocketPollingEnabled(socket)) { // Socket with that fd is already polled return false; } int *fd = ALLOCATE_OBJECT(int); *fd = socket->fd; g_hash_table_insert(poll_table, fd, socket); return true; } API bool isSocketPollingEnabled(Socket *socket) { return g_hash_table_lookup(poll_table, &socket->fd) != NULL; } API bool disableSocketPolling(Socket *socket) { return g_hash_table_remove(poll_table, &socket->fd) == true; } API void pollSockets() { if(!polling) { polling = true; // set polling flag to lock our poll table in order to make this function reentrancy safe if(!g_queue_is_empty(connecting)) { GQueue *connectingSockets = g_queue_copy(connecting); // copy the connecting socket list so we may modify the list while polling for(GList *iter = connectingSockets->head; iter != NULL; iter = iter->next) { if(pollConnectingSocket(iter->data)) { // poll the connecting socket // The socket should no longer be polled g_queue_remove(connecting, iter->data); // remove it from the original connecting queue } } g_queue_free(connectingSockets); // remove our temporary iteration list } GList *sockets = g_hash_table_get_values(poll_table); // get a static list of sockets so we may modify the hash table while polling for(GList *iter = sockets; iter != NULL; iter = iter->next) { Socket *poll = iter->data; int fd; // storage for the file descriptor that won't be available anymore in case the socket gets freed before we remove it if(pollSocket(poll, &fd)) { // poll the socket // The socket should no longer be polled g_hash_table_remove(poll_table, &fd); // remove it from the polling table } } g_list_free(sockets); // remove our temporary iteration list polling = false; // release pseudo lock on poll table } } API bool isSocketsPolling() { return polling; } API Socket *getPolledSocketByFd(int fd) { return g_hash_table_lookup(poll_table, &fd); } /** * Callback to poll all sockets signed up for polling */ TIMER_CALLBACK(poll) { pollSockets(); triggerEvent(NULL, "sockets_polled"); TIMER_ADD_TIMEOUT(pollInterval, poll); } /** * Polls a connecting socket and notifies the caller of whether it should be removed from the connecting polling queue afterwards * * @param socket the connecting socket to poll * @result true if the socket should be removed from the connecting polling queue after polling */ static bool pollConnectingSocket(Socket *socket) { assert(!socket->connected); assert(socket->type == SOCKET_CLIENT); assert(socket->custom != NULL); // Check whether the socket has timed out yet AsyncConnectionTimer *timer = socket->custom; if(getMicroTime() - timer->creationTime > timer->timeout) { // connection timed out logWarning("Asynchronous connection on socket %d timed out", socket->fd); closeSocket(socket); triggerEvent(socket, "disconnect"); return true; } // Initialize timeout struct timeval tv = {0, 0}; // Initialize write fd set fd_set fdset; FD_ZERO(&fdset); FD_SET(socket->fd, &fdset); // Select socket for write flag (connected) int ret; if((ret = select(socket->fd + 1, NULL, &fdset, NULL, &tv)) < 0) { #ifdef WIN32 if(WSAGetLastError() != WSAEINTR) { char *error = g_win32_error_message(WSAGetLastError()); logError("Error selecting socket %d for write flag (connected) while polling: %s", socket->fd, error); free(error); #else if(errno != EINTR) { logSystemError("Error selecting socket %d for write flag (connected) while polling", socket->fd); #endif closeSocket(socket); triggerEvent(socket, "disconnect"); return true; } // EINTR at this point means the socket is just not connected yet, so we can safely return and continue polling another time return false; } else if(ret > 0) { // there is a write flag on the socket // Socket selected for write, check if we're indeed connected int valopt; socklen_t lon = sizeof(int); if(getsockopt(socket->fd, SOL_SOCKET, SO_ERROR, (void*) (&valopt), &lon) < 0) { logSystemError("getsockopt() failed on socket %d", socket->fd); closeSocket(socket); triggerEvent(socket, "disconnect"); return true; } else if(valopt != 0) { // There was a connection error logSystemError("Asynchronous connection on socket %d failed", socket->fd); closeSocket(socket); triggerEvent(socket, "disconnect"); return true; } logNotice("Asynchronously connected socket %d", socket->fd); socket->connected = true; triggerEvent(socket, "connected"); enableSocketPolling(socket); return true; } // the socket doesn't have a write flag, so let's just wait until it's connected return false; } /** * Polls a socket and notifies the caller of whether it should be removed from the polling table afterwards * * @param socket the socket to poll * @param fd_p a pointer to an integer field to which the file descriptor of the socket should be written in case the socket should be removed from the polling table and could already be freed at that time * @result true if the socket should be removed from the polling table after polling */ static bool pollSocket(Socket *socket, int *fd_p) { *fd_p = socket->fd; // backup file descriptor if(!socket->connected) { // Socket is disconnected triggerEvent(socket, "disconnect"); return true; } if(socket->type != SOCKET_SERVER && socket->type != SOCKET_SERVER_BLOCK) { int ret; if((ret = socketReadRaw(socket, poll_buffer, SOCKET_POLL_BUFSIZE)) < 0) { if(socket->connected) { // socket is still connected, so the error was not fatal triggerEvent(socket, "error"); return false; } else { // socket was disconnected either by the peer or by a fatal error triggerEvent(socket, "disconnect"); return true; } } else if(ret > 0) { // we actually read something triggerEvent(socket, "read", poll_buffer, ret); } // else nothing to read right now } else { Socket *clientSocket; if((clientSocket = socketAccept(socket)) != NULL) { triggerEvent(socket, "accept", clientSocket); } else { if(socket->connected) { // socket is still connected, so the error was not fatal triggerEvent(socket, "error"); return false; } else { // socket was disconnected either by the peer or by a fatal error triggerEvent(socket, "disconnect"); return true; } } } return false; }
/* ###### Main program ################################################### */ int main(int argc, char** argv) { union sockaddr_union localAddress; struct pollfd ufds; struct SimpleRedBlackTree objectStorage; struct SimpleRedBlackTree objectDisplay; struct SimpleRedBlackTreeNode* node; unsigned long long now; unsigned long long updateInterval = 1000000; unsigned long long purgeInterval = 30000000; unsigned long long lastUpdate = 0; size_t lastElements = ~0; size_t elements; int result; int reuse; int sd; int n; if(checkIPv6()) { string2address("[::]:0", &localAddress); setPort(&localAddress.sa, 2960); } else { string2address("0.0.0.0:0", &localAddress); setPort(&localAddress.sa, 2960); } for(n = 1;n < argc;n++) { if(!(strncmp(argv[n], "-localaddress=", 14))) { if(string2address((char*)&argv[n][14], &localAddress) == false) { fprintf(stderr, "ERROR: Bad local address <%s>\n", (char*)&argv[n][14]); exit(1); } } else if(!(strncmp(argv[n], "-updateinterval=", 16))) { updateInterval = 1000 * atol((char*)&argv[n][16]); if(updateInterval < 100000) { updateInterval = 100000; } } else if(!(strncmp(argv[n], "-purgeinterval=", 15))) { purgeInterval = 1000 * atol((const char*)&argv[n][15]); if(purgeInterval < 1000000) { purgeInterval = 1000000; } } else if(!(strncmp(argv[n], "-maxpr=", 7))) { maxPRs = atoi((const char*)&argv[n][7]); } else if(!(strncmp(argv[n], "-maxpe=", 7))) { maxPEs = atoi((const char*)&argv[n][7]); } else if(!(strncmp(argv[n], "-maxpu=", 7))) { maxPUs = atoi((const char*)&argv[n][7]); } else if(!(strncmp(argv[n], "-maxlocationsize=", 17))) { maxLocationSize = atoi((const char*)&argv[n][17]); } else if(!(strcmp(argv[n], "-compact"))) { useCompactMode = true; } else if(!(strcmp(argv[n], "-full"))) { useCompactMode = false; } else { printf("Bad argument \"%s\"!\n" ,argv[n]); fprintf(stderr, "Usage: %s {-localaddress=address:port} {-updateinterval=milliseconds} {-purgeinterval=milliseconds} {-compact|-full} {-maxpr=PRs} {-maxpe=PEs} {-maxpu=PUs} {-maxlocationsize=characters}\n", argv[0]); exit(1); } } sd = ext_socket(localAddress.sa.sa_family, SOCK_DGRAM, IPPROTO_UDP); if(sd < 0) { perror("Unable to create socket"); exit(1); } reuse = 1; if(ext_setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) { perror("setsockopt() with SO_REUSEADDR failed"); } if(bindplus(sd, &localAddress, 1) == false) { fputs("ERROR: Unable to bind socket to local address\n", stderr); exit(1); } simpleRedBlackTreeNew(&objectStorage, NULL, cspObjectStorageComparison); simpleRedBlackTreeNew(&objectDisplay, cspObjectDisplayPrint, cspObjectDisplayComparison); puts("Component Status Monitor - Version 1.0"); puts("======================================\n"); installBreakDetector(); printf("\x1b[;H\x1b[2J"); /* The first update should be in 1 second ... */ lastUpdate = getMicroTime() + 1000000 - updateInterval; while(!breakDetected()) { ufds.fd = sd; ufds.events = POLLIN; now = getMicroTime(); while(now - lastUpdate < updateInterval) { now = getMicroTime(); result = ext_poll(&ufds, 1, ((lastUpdate + updateInterval) > now) ? (int)((lastUpdate + updateInterval - now) / 1000) : 0); if((result > 0) && (ufds.revents & POLLIN)) { handleMessage(sd, &objectStorage, &objectDisplay); } else if((result < 0) && (errno == EINTR)) { goto finished; } } purgeCSPObjects(&objectStorage, &objectDisplay, purgeInterval); elements = simpleRedBlackTreeGetElements(&objectStorage); if( (elements != lastElements) || (elements > 0) ) { printf("\x1b[;H"); printTimeStamp(stdout); printf("Current Component Status -- \x1b[31;1m%u PRs\x1b[0m, \x1b[34;1m%u PEs\x1b[0m, \x1b[32;1m%u PUs\x1b[0m\x1b[0K\n\x1b[0K\n\x1b[0K\x1b[;H\n", totalPRs, totalPEs, totalPUs); maxObjectLabelSize = 0; currentPRs = 0; currentPEs = 0; currentPUs = 0; node = simpleRedBlackTreeGetFirst(&objectDisplay); while(node != NULL) { cspObjectDisplayPrint(node, stdout); node = simpleRedBlackTreeGetNext(&objectDisplay, node); } currentObjectLabelSize = maxObjectLabelSize; printf("\x1b[0J"); fflush(stdout); } lastElements = elements; lastUpdate = now; } finished: ext_close(sd); simpleRedBlackTreeDelete(&objectStorage); puts("\nTerminated!"); return(0); }
/* ###### Handle incoming CSP message #################################### */ static void handleMessage(int sd, struct SimpleRedBlackTree* objectStorage, struct SimpleRedBlackTree* objectDisplay) { struct ComponentStatusReport* cspReport; struct CSPObject* cspObject; char buffer[65536]; ssize_t received; size_t i; received = ext_recv(sd, (char*)&buffer, sizeof(buffer), 0); if(received) { cspReport = (struct ComponentStatusReport*)&buffer; if( (received >= (ssize_t)sizeof(struct ComponentStatusReport)) && (cspReport->Header.Type == CSPT_REPORT) && (ntohl(cspReport->Header.Version) == CSP_VERSION) ) { cspReport->Header.Version = ntohl(cspReport->Header.Version); cspReport->Header.Length = ntohs(cspReport->Header.Length); cspReport->Header.SenderID = ntoh64(cspReport->Header.SenderID); cspReport->Header.SenderTimeStamp = ntoh64(cspReport->Header.SenderTimeStamp); cspReport->ReportInterval = ntohl(cspReport->ReportInterval); cspReport->Workload = ntohs(cspReport->Workload); cspReport->Associations = ntohs(cspReport->Associations); if(sizeof(struct ComponentStatusReport) + (cspReport->Associations * sizeof(struct ComponentAssociation)) == (size_t)received) { for(i = 0;i < cspReport->Associations;i++) { cspReport->AssociationArray[i].ReceiverID = ntoh64(cspReport->AssociationArray[i].ReceiverID); cspReport->AssociationArray[i].Duration = ntoh64(cspReport->AssociationArray[i].Duration); cspReport->AssociationArray[i].Flags = ntohs(cspReport->AssociationArray[i].Flags); cspReport->AssociationArray[i].ProtocolID = ntohs(cspReport->AssociationArray[i].ProtocolID); cspReport->AssociationArray[i].PPID = ntohl(cspReport->AssociationArray[i].PPID); } cspObject = findCSPObject(objectStorage, cspReport->Header.SenderID); if(cspObject == NULL) { cspObject = (struct CSPObject*)malloc(sizeof(struct CSPObject)); if(cspObject) { simpleRedBlackTreeNodeNew(&cspObject->StorageNode); simpleRedBlackTreeNodeNew(&cspObject->DisplayNode); cspObject->Identifier = cspReport->Header.SenderID; cspObject->AssociationArray = NULL; switch(CID_GROUP(cspObject->Identifier)) { case CID_GROUP_REGISTRAR: totalPRs++; break; case CID_GROUP_POOLELEMENT: totalPEs++; break; case CID_GROUP_POOLUSER: totalPUs++; break; } } } if(cspObject) { if(simpleRedBlackTreeNodeIsLinked(&cspObject->DisplayNode)) { /* The position within the objectDisplay storage may change, due to updated locationArray! */ CHECK(simpleRedBlackTreeRemove(objectDisplay, &cspObject->DisplayNode) == &cspObject->DisplayNode); simpleRedBlackTreeVerify(objectDisplay); } if(cspReport->Header.Flags != 0x00) { cspObject->LastReportTimeStamp = 0; } else { cspObject->LastReportTimeStamp = getMicroTime(); cspObject->SenderTimeStamp = cspReport->Header.SenderTimeStamp; cspObject->ReportInterval = cspReport->ReportInterval; cspObject->Workload = CSR_GET_WORKLOAD(cspReport->Workload); getDescriptionForID(cspObject->Identifier, (char*)&cspObject->Description, sizeof(cspObject->Description)); memcpy(&cspObject->Status, &cspReport->Status, sizeof(cspObject->Status)); cspObject->Status[sizeof(cspObject->Status) - 1] = 0x00; memcpy(&cspObject->Location, &cspReport->Location, sizeof(cspObject->Location)); /* DisplayNode MUST be re-inserted, since the location may change and the location is part of the sorting key! */ /* for(int i=0;i < 6;i++) { cspObject->Location[i] = 'A' + (random() % 26); } */ cspObject->Location[sizeof(cspObject->Location) - 1] = 0x00; } if(cspObject->AssociationArray) { deleteComponentAssociationArray(cspObject->AssociationArray); } cspObject->AssociationArray = createComponentAssociationArray(cspReport->Associations); CHECK(cspObject->AssociationArray); memcpy(cspObject->AssociationArray, &cspReport->AssociationArray, cspReport->Associations * sizeof(struct ComponentAssociation)); cspObject->Associations = cspReport->Associations; CHECK(simpleRedBlackTreeInsert(objectStorage, &cspObject->StorageNode) == &cspObject->StorageNode); simpleRedBlackTreeVerify(objectStorage); CHECK(simpleRedBlackTreeInsert(objectDisplay, &cspObject->DisplayNode) == &cspObject->DisplayNode); simpleRedBlackTreeVerify(objectDisplay); } } } } }
/* ###### Purge out-of-date CSPObject in storage ######################### */ void purgeCSPObjects(struct SimpleRedBlackTree* objectStorage, struct SimpleRedBlackTree* objectDisplay, const unsigned long long purgeInterval) { struct CSPObject* cspObject; struct CSPObject* nextCSPObject; cspObject = (struct CSPObject*)simpleRedBlackTreeGetFirst(objectStorage); while(cspObject != NULL) { nextCSPObject = (struct CSPObject*)simpleRedBlackTreeGetNext(objectStorage, &cspObject->StorageNode); if(cspObject->LastReportTimeStamp + min(purgeInterval, (10 * cspObject->ReportInterval)) < getMicroTime()) { CHECK(simpleRedBlackTreeRemove(objectStorage, &cspObject->StorageNode) == &cspObject->StorageNode); switch(CID_GROUP(cspObject->Identifier)) { case CID_GROUP_REGISTRAR: assert(totalPRs > 0); totalPRs--; break; case CID_GROUP_POOLELEMENT: assert(totalPEs > 0); totalPEs--; break; case CID_GROUP_POOLUSER: assert(totalPUs > 0); totalPUs--; break; } simpleRedBlackTreeVerify(objectStorage); CHECK(simpleRedBlackTreeRemove(objectDisplay, &cspObject->DisplayNode) == &cspObject->DisplayNode); simpleRedBlackTreeVerify(objectDisplay); simpleRedBlackTreeNodeDelete(&cspObject->StorageNode); simpleRedBlackTreeNodeDelete(&cspObject->DisplayNode); free(cspObject->AssociationArray); free(cspObject); } cspObject = nextCSPObject; } }
/* ###### CSPObject print function ####################################### */ static void cspObjectDisplayPrint(const void* cspObjectPtr, FILE* fd) { const struct CSPObject* cspObject = getCSPObjectFromDisplayNode(cspObjectPtr); char idString[256]; char protocolString[64]; char workloadString[32]; char locationString[sizeof(cspObject->Location)]; char uptimeString[32]; char objectLabelString[256]; char space[256]; size_t objectLabelSize; unsigned int h, m, s; size_t i; int color; color = 0; /* ====== Check component number limit to display ===================== */ if(CID_GROUP(cspObject->Identifier) == CID_GROUP_REGISTRAR) { color = 31; currentPRs++; if(currentPRs > maxPRs) { if(currentPRs == maxPRs + 1) { fprintf(fd, "\n\x1b[%u;47m(%u further PRs have been hidden)\x1b[0m", color, totalPRs -maxPRs); } return; } } else if(CID_GROUP(cspObject->Identifier) == CID_GROUP_POOLELEMENT) { color = 34; currentPEs++; if(currentPEs > maxPEs) { if(currentPEs == maxPEs + 1) { fprintf(fd, "\n\x1b[%u;47m(%u further PEs have been hidden)\x1b[0m", color, totalPEs -maxPEs); } return; } } else if(CID_GROUP(cspObject->Identifier) == CID_GROUP_POOLUSER) { color = 32; currentPUs++; if(currentPUs > maxPUs) { if(currentPUs == maxPUs + 1) { fprintf(fd, "\n\x1b[%u;47m(%u further PUs have been hidden)\x1b[0m", color, totalPUs -maxPUs); } return; } } /* ====== Get workload string ========================================= */ if(cspObject->Workload >= 0.00) { if(cspObject->Workload < 0.90) { snprintf((char*)&workloadString, sizeof(workloadString), " L=%3u%%", (unsigned int)rint(100.0 * cspObject->Workload)); } else { snprintf((char*)&workloadString, sizeof(workloadString), " L=\x1b[7m%3u%%\x1b[27m", (unsigned int)rint(100.0 * cspObject->Workload)); } } else { workloadString[0] = 0x00; } /* ====== Get uptime string =========================================== */ h = (unsigned int)(cspObject->SenderTimeStamp / (3600ULL * 1000000ULL)); if(h < 100) { m = (unsigned int)((cspObject->SenderTimeStamp / (60ULL * 1000000ULL)) % 60); s = (unsigned int)((cspObject->SenderTimeStamp / 1000000ULL) % 60); snprintf((char*)&uptimeString, sizeof(uptimeString), "%02u:%02u:%02u", h, m, s); } else { if((h / 24) < 15000) { snprintf((char*)&uptimeString, sizeof(uptimeString), "%3ud %02uh", h / 24, h % 24); } else { safestrcpy((char*)&uptimeString, "??:??:??", sizeof(uptimeString)); } } /* ====== Get object label string ===================================== */ maxLocationSize = min(maxLocationSize, sizeof(cspObject->Location) - 1); memcpy((char*)&locationString, cspObject->Location, sizeof(cspObject->Location)); i = strlen(locationString); if(i > maxLocationSize) { if(maxLocationSize >= 3) { locationString[maxLocationSize - 1] = '.'; locationString[maxLocationSize - 2] = '.'; locationString[maxLocationSize - 3] = '.'; } locationString[maxLocationSize] = 0x00; } snprintf((char*)&objectLabelString, sizeof(objectLabelString), "\n%s [%s]", cspObject->Description, locationString); objectLabelSize = strlen(objectLabelString); maxObjectLabelSize = max(maxObjectLabelSize, objectLabelSize); if(currentObjectLabelSize > objectLabelSize) { for(i = 0;i < min(sizeof(space) - 1, currentObjectLabelSize - objectLabelSize); i++) { space[i] = ' '; } space[i] = 0x00; } else { space[0] = 0x00; } fprintf(fd, "\x1b[%u;1m%s\x1b[0m\x1b[%um %s", color, objectLabelString, color, space); fprintf(fd, "U=%s l=%1.1fs A=%u%s \"%s\"\x1b[0K", uptimeString, (double)abs(((int64_t)cspObject->LastReportTimeStamp - (int64_t)getMicroTime()) / 1000) / 1000.0, (unsigned int)cspObject->Associations, workloadString, cspObject->Status); if(!useCompactMode) { for(i = 0;i < cspObject->Associations;i++) { getDescriptionForID(cspObject->AssociationArray[i].ReceiverID, (char*)&idString, sizeof(idString)); getDescriptionForProtocol(cspObject->AssociationArray[i].ProtocolID, cspObject->AssociationArray[i].PPID, (char*)&protocolString, sizeof(protocolString)); fprintf(fd, "\n -> %s %s", idString, protocolString); if(cspObject->AssociationArray[i].Duration != ~0ULL) { h = (unsigned int)(cspObject->AssociationArray[i].Duration / (3600ULL * 1000000ULL)); m = (unsigned int)((cspObject->AssociationArray[i].Duration / (60ULL * 1000000ULL)) % 60); s = (unsigned int)((cspObject->AssociationArray[i].Duration / 1000000ULL) % 60); fprintf(fd, " duration=%u:%02u:%02u", h, m, s); } fputs("\x1b[0K", fd); } } fputs("\x1b[0m\x1b[0K", fd); }
void hipaccStartTiming() { start_time = getMicroTime(); }
unsigned long long now; if(nextPoolUserNode == NULL) { nextPoolUserNode = (struct ST_CLASS(PoolUserNode)*)malloc(sizeof(struct ST_CLASS(PoolUserNode))); if(nextPoolUserNode == NULL) { /* Giving permission here seems to be useful in case of trying to avoid DoS when - for some reason - the PR's memory is full. */ return(true); } } ST_CLASS(poolUserNodeNew)(nextPoolUserNode, fd, assocID); poolUserNode = ST_CLASS(poolUserListAddOrUpdatePoolUserNode)(®istrar->PoolUsers, &nextPoolUserNode); CHECK(poolUserNode != NULL); now = getMicroTime(); rate = threshold = -1.0; switch(action) { case AHT_HANDLE_RESOLUTION: rate = ST_CLASS(poolUserNodeNoteHandleResolution)(poolUserNode, poolHandle, now, TSHT_BUCKETS, TSHT_ENTRIES); threshold = registrar->MaxHRRate; break; case AHT_ENDPOINT_UNREACHABLE: rate = ST_CLASS(poolUserNodeNoteEndpointUnreachable)(poolUserNode, poolHandle, peIdentifier, now, TSHT_BUCKETS, TSHT_ENTRIES); threshold = registrar->MaxEURate; break; default: CHECK(false); } /* printf("rate=%1.6f threshold=%1.6f\n", rate, threshold); */