void newResult(Task *t) { pmResult *rslt; Symbol *sym; pmValueSet *vset; pmValueBlock *vblk; int i; int len; /* allocate pmResult */ rslt = (pmResult *) zalloc(sizeof(pmResult) + (t->nrules - 1) * sizeof(pmValueSet *)); rslt->numpmid = t->nrules; /* allocate pmValueSet's */ sym = t->rules; for (i = 0; i < t->nrules; i++) { vset = (pmValueSet *)alloc(sizeof(pmValueSet)); vset->pmid = agentId(symName(*sym)); vset->numval = 0; vset->valfmt = PM_VAL_DPTR; vset->vlist[0].inst = PM_IN_NULL; len = PM_VAL_HDR_SIZE + sizeof(double); vblk = (pmValueBlock *)zalloc(len); vblk->vlen = len; vblk->vtype = PM_TYPE_DOUBLE; vset->vlist[0].value.pval = vblk; rslt->vset[i] = vset; sym++; } t->rslt = rslt; }
char *AsmBuf::ExtractPublicSymbol(char *sName) { String str; String symName(sName); int st,nd,nd1; st = 0; String s1((char *)"public"); j1: s1.add(symName); st =find(s1, st); if (st < 0) return (char *)""; // Make sure the name matches exactly, and is not a substring. if (IsIdentChar(buf()[st+7+symName.len()])) { st += 7+symName.len(); goto j1; } s1.copy("endpublic"); nd = find(s1,st); if (nd < 0) return (char *)""; s1.copy("\r\n"); nd1 = find(s1,nd); if (nd1 > 0) nd = nd1; else nd += 9; // skip over to end of "endpublic" str.copy(&buf()[st],nd-st); return str.buf(); }
int main(int argc, char **argv) { if (argc != 4) { print_usage(); return EXIT_FAILURE; } std::ifstream inFile(argv[1], std::ios::in); if (!inFile) { std::cerr << "Failed to open input file \"" << argv[1] << "\"\n"; return EXIT_FAILURE; } std::ofstream outFile(argv[2], std::ios::out); std::string symName(argv[3]); std::string sanitisedFileName(argv[2]); std::string allowedChars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_"); size_t pos = sanitisedFileName.find_first_not_of(allowedChars, 0); while (pos != std::string::npos) { sanitisedFileName[pos] = '_'; pos = sanitisedFileName.find_first_not_of(allowedChars, pos); } inFile.seekg(0, std::ios::end); size_t fileSize = inFile.tellg(); inFile.seekg(0, std::ios::beg); outFile << "/* AUTOGENERATED HEADER */\n" << "#ifndef __" << sanitisedFileName << "\n" << "#define __" << sanitisedFileName << "\n"; outFile << "struct {\n" << "\tunsigned int size;\n" << "\tunsigned char data[" << fileSize << "];\n" << "} " << symName << " = {\n" << "\t.size = " << fileSize << ",\n" << "\t.data = {"; for (size_t b = 0; b < fileSize ;b++) { unsigned char byte; if (b%10 == 0) outFile << "\n\t"; inFile.read((char*)&byte, 1); outFile << std::hex << "0x" << (unsigned int)byte << ", "; } outFile << "\t}\n" << "};\n"; outFile << "#endif\n"; }
void __dumpMetric(int level, Metric *m) { int i; int j; int numinst; for (i = 0; i < level; i++) fprintf(stderr, ".. "); fprintf(stderr, "Metric dump @ " PRINTF_P_PFX "%p\n", m); for (i = 0; i < level; i++) fprintf(stderr, ".. "); fprintf(stderr, "expr=" PRINTF_P_PFX "%p profile=" PRINTF_P_PFX "%p host=" PRINTF_P_PFX "%p next=" PRINTF_P_PFX "%p prev=" PRINTF_P_PFX "%p\n", m->expr, m->profile, m->host, m->next, m->prev); for (i = 0; i < level; i++) fprintf(stderr, ".. "); fprintf(stderr, "metric=%s host=%s via=%s conv=%g specinst=%d m_indom=%d\n", symName(m->mname), symName(m->hname), symName(m->hconn), m->conv, m->specinst, m->m_idom); if (m->desc.indom != PM_INDOM_NULL) { numinst = m->specinst == 0 ? m->m_idom : m->specinst; for (j = 0; j < numinst; j++) { for (i = 0; i < level; i++) fprintf(stderr, ".. "); fprintf(stderr, "[%d] iid=", j); if (m->iids[j] == PM_IN_NULL) fprintf(stderr, "?missing"); else fprintf(stderr, "%d", m->iids[j]); fprintf(stderr, " iname=\"%s\"\n", m->inames[j]); } } for (i = 0; i < level; i++) fprintf(stderr, ".. "); fputc('\n', stderr); #if 0 pmDesc desc; /* pmAPI metric description */ RealTime stamp; /* time stamp for current values */ pmValueSet *vset; /* current values */ RealTime stomp; /* previous time stamp for rate calculation */ double *vals; /* vector of values for rate computation */ int offset; /* offset within sample in expr ring buffer */ ... Metric; #endif }
void dumpTask(Task *t) { int i; fprintf(stderr, "Task dump @ " PRINTF_P_PFX "%p\n", t); fprintf(stderr, " nth=%d delta=%.3f tick=%d next=" PRINTF_P_PFX "%p prev=" PRINTF_P_PFX "%p\n", t->nth, t->delta, t->tick, t->next, t->prev); fprintf(stderr, " eval time: "); showFullTime(stderr, t->eval); fputc('\n', stderr); fprintf(stderr, " retry time: "); showFullTime(stderr, t->retry); fputc('\n', stderr); if (t->hosts == NULL) fprintf(stderr, " host=<null>\n"); else fprintf(stderr, " host=%s via=%s (%s)\n", symName(t->hosts->name), symName(t->hosts->conn), t->hosts->down ? "down" : "up"); fprintf(stderr, " rules:\n"); for (i = 0; i < t->nrules; i++) { fprintf(stderr, " %s\n", symName(t->rules[i])); } }
void dumpRules(void) { Task *t; Symbol *s; int i; for (t = taskq; t != NULL; t = t->next) { s = t->rules; for (i = 0; i < t->nrules; i++, s++) { fprintf(stderr, "\nRule: %s\n", symName(*s)); dumpTree((Expr *)symValue(*s)); } } }
/* try to reconnect to hosts and initialize missing metrics */ static void enable(Task *t) { Host *h; Metric *m; Metric **p; h = t->hosts; while (h) { /* reconnect to host */ if (h->down) { if (reconnect(h)) { h->down = 0; host_state_changed(symName(h->name), STATE_RECONN); } } /* reinitialize waiting Metrics */ if ((! h->down) && (h->waits)) { p = &h->waits; m = *p; while (m) { switch (reinitMetric(m)) { case 1: *p = m->next; unwaitMetric(m); bundleMetric(h,m); break; case 0: p = &m->next; break; case -1: *p = m->next; m->next = h->duds; h->duds = m; break; } m = *p; } } h = h->next; } }
Handle poly_ffi(TaskData *taskData, Handle args, Handle code) { unsigned c = get_C_unsigned(taskData, code->Word()); switch (c) { case 0: // malloc { POLYUNSIGNED size = getPolyUnsigned(taskData, args->Word()); return toSysWord(taskData, malloc(size)); } case 1: // free { void *mem = *(void**)(args->WordP()); free(mem); return taskData->saveVec.push(TAGGED(0)); } case 2: // Load library { TempString libName(args->Word()); #if (defined(_WIN32) && ! defined(__CYGWIN__)) HINSTANCE lib = LoadLibrary(libName); if (lib == NULL) { char buf[256]; #if (defined(UNICODE)) _snprintf(buf, sizeof(buf), "Loading <%S> failed. Error %lu", libName, GetLastError()); #else _snprintf(buf, sizeof(buf), "Loading <%s> failed. Error %lu", libName, GetLastError()); #endif buf[sizeof(buf)-1] = 0; // Terminate just in case raise_exception_string(taskData, EXC_foreign, buf); } #else void *lib = dlopen(libName, RTLD_LAZY); if (lib == NULL) { char buf[256]; snprintf(buf, sizeof(buf), "Loading <%s> failed: %s", (const char *)libName, dlerror()); buf[sizeof(buf)-1] = 0; // Terminate just in case raise_exception_string(taskData, EXC_foreign, buf); } #endif return toSysWord(taskData, lib); } case 3: // Load address of executable. { #if (defined(_WIN32) && ! defined(__CYGWIN__)) HINSTANCE lib = hApplicationInstance; #else void *lib = dlopen(NULL, RTLD_LAZY); if (lib == NULL) { char buf[256]; snprintf(buf, sizeof(buf), "Loading address of executable failed: %s", dlerror()); buf[sizeof(buf)-1] = 0; // Terminate just in case raise_exception_string(taskData, EXC_foreign, buf); } #endif return toSysWord(taskData, lib); } case 4: // Unload library - Is this actually going to be used? { #if (defined(_WIN32) && ! defined(__CYGWIN__)) HMODULE hMod = *(HMODULE*)(args->WordP()); if (! FreeLibrary(hMod)) raise_syscall(taskData, "FreeLibrary failed", -(int)GetLastError()); #else void *lib = *(void**)(args->WordP()); if (dlclose(lib) != 0) { char buf[256]; snprintf(buf, sizeof(buf), "dlclose failed: %s", dlerror()); buf[sizeof(buf)-1] = 0; // Terminate just in case raise_exception_string(taskData, EXC_foreign, buf); } #endif return taskData->saveVec.push(TAGGED(0)); } case 5: // Load the address of a symbol from a library. { TempCString symName(args->WordP()->Get(1)); #if (defined(_WIN32) && ! defined(__CYGWIN__)) HMODULE hMod = *(HMODULE*)(args->WordP()->Get(0).AsAddress()); void *sym = (void*)GetProcAddress(hMod, symName); if (sym == NULL) { char buf[256]; _snprintf(buf, sizeof(buf), "Loading symbol <%s> failed. Error %lu", symName, GetLastError()); buf[sizeof(buf)-1] = 0; // Terminate just in case raise_exception_string(taskData, EXC_foreign, buf); } #else void *lib = *(void**)(args->WordP()->Get(0).AsAddress()); void *sym = dlsym(lib, symName); if (sym == NULL) { char buf[256]; snprintf(buf, sizeof(buf), "load_sym <%s> : %s", (const char *)symName, dlerror()); buf[sizeof(buf)-1] = 0; // Terminate just in case raise_exception_string(taskData, EXC_foreign, buf); } #endif return toSysWord(taskData, sym); } // Libffi functions case 50: // Return a list of available ABIs return makeList(taskData, sizeof(abiTable)/sizeof(abiTable[0]), (char*)abiTable, sizeof(abiTable[0]), 0, mkAbitab); case 51: // A constant from the table { unsigned index = get_C_unsigned(taskData, args->Word()); if (index >= sizeof(constantTable) / sizeof(constantTable[0])) raise_exception_string(taskData, EXC_foreign, "Index out of range"); return Make_arbitrary_precision(taskData, constantTable[index]); } case 52: // Return an FFI type { unsigned index = get_C_unsigned(taskData, args->Word()); if (index >= sizeof(ffiTypeTable) / sizeof(ffiTypeTable[0])) raise_exception_string(taskData, EXC_foreign, "Index out of range"); return toSysWord(taskData, ffiTypeTable[index]); } case 53: // Extract fields from ffi type. { ffi_type *ffit = *(ffi_type**)(args->WordP()); Handle sizeHandle = Make_arbitrary_precision(taskData, ffit->size); Handle alignHandle = Make_arbitrary_precision(taskData, ffit->alignment); Handle typeHandle = Make_arbitrary_precision(taskData, ffit->type); Handle elemHandle = toSysWord(taskData, ffit->elements); Handle resHandle = alloc_and_save(taskData, 4); resHandle->WordP()->Set(0, sizeHandle->Word()); resHandle->WordP()->Set(1, alignHandle->Word()); resHandle->WordP()->Set(2, typeHandle->Word()); resHandle->WordP()->Set(3, elemHandle->Word()); return resHandle; } case 54: // Construct an ffi type. { // This is probably only used to create structs. size_t size = getPolyUnsigned(taskData, args->WordP()->Get(0)); unsigned short align = get_C_ushort(taskData, args->WordP()->Get(1)); unsigned short type = get_C_ushort(taskData, args->WordP()->Get(2)); unsigned nElems = 0; for (PolyWord p = args->WordP()->Get(3); !ML_Cons_Cell::IsNull(p); p = ((ML_Cons_Cell*)p.AsObjPtr())->t) nElems++; size_t space = sizeof(ffi_type); // If we need the elements add space for the elements plus // one extra for the zero terminator. if (nElems != 0) space += (nElems+1) * sizeof(ffi_type *); ffi_type *result = (ffi_type*)malloc(space); // Raise an exception rather than returning zero. if (result == 0) raise_syscall(taskData, "Insufficient memory", ENOMEM); ffi_type **elem = 0; if (nElems != 0) elem = (ffi_type **)(result+1); memset(result, 0, sizeof(ffi_type)); // Zero it in case they add fields result->size = size; result->alignment = align; result->type = type; result->elements = elem; if (elem != 0) { for (PolyWord p = args->WordP()->Get(3); !ML_Cons_Cell::IsNull(p); p = ((ML_Cons_Cell*)p.AsObjPtr())->t) { PolyWord e = ((ML_Cons_Cell*)p.AsObjPtr())->h; *elem++ = *(ffi_type**)(e.AsAddress()); } *elem = 0; } return toSysWord(taskData, result); } case 55: // Create a CIF. This contains all the types and some extra information. // The result is in allocated memory followed immediately by the argument type vector. { ffi_abi abi = (ffi_abi)get_C_ushort(taskData, args->WordP()->Get(0)); ffi_type *rtype = *(ffi_type **)args->WordP()->Get(1).AsAddress(); unsigned nArgs = 0; for (PolyWord p = args->WordP()->Get(2); !ML_Cons_Cell::IsNull(p); p = ((ML_Cons_Cell*)p.AsObjPtr())->t) nArgs++; // Allocate space for the cif followed by the argument type vector size_t space = sizeof(ffi_cif) + nArgs * sizeof(ffi_type*); ffi_cif *cif = (ffi_cif *)malloc(space); if (cif == 0) raise_syscall(taskData, "Insufficient memory", ENOMEM); ffi_type **atypes = (ffi_type **)(cif+1); // Copy the arguments types. ffi_type **at = atypes; for (PolyWord p = args->WordP()->Get(2); !ML_Cons_Cell::IsNull(p); p = ((ML_Cons_Cell*)p.AsObjPtr())->t) { PolyWord e = ((ML_Cons_Cell*)p.AsObjPtr())->h; *at++ = *(ffi_type**)(e.AsAddress()); } ffi_status status = ffi_prep_cif(cif, abi, nArgs, rtype, atypes); if (status == FFI_BAD_TYPEDEF) raise_exception_string(taskData, EXC_foreign, "Bad typedef in ffi_prep_cif"); else if (status == FFI_BAD_ABI) raise_exception_string(taskData, EXC_foreign, "Bad ABI in ffi_prep_cif"); else if (status != FFI_OK) raise_exception_string(taskData, EXC_foreign, "Error in ffi_prep_cif"); return toSysWord(taskData, cif); } case 56: // Call a function. { ffi_cif *cif = *(ffi_cif **)args->WordP()->Get(0).AsAddress(); void *f = *(void**)args->WordP()->Get(1).AsAddress(); void *res = *(void**)args->WordP()->Get(2).AsAddress(); void **arg = *(void***)args->WordP()->Get(3).AsAddress(); // We release the ML memory across the call so a GC can occur // even if this thread is blocked in the C code. processes->ThreadReleaseMLMemory(taskData); ffi_call(cif, FFI_FN(f), res, arg); processes->ThreadUseMLMemory(taskData); return taskData->saveVec.push(TAGGED(0)); } case 57: // Create a callback. { #ifdef INTERPRETED raise_exception_string(taskData, EXC_foreign, "Callbacks are not implemented in the byte code interpreter"); #endif Handle mlFunction = taskData->saveVec.push(args->WordP()->Get(0)); ffi_cif *cif = *(ffi_cif **)args->WordP()->Get(1).AsAddress(); void *resultFunction; // Allocate the memory. resultFunction is set to the executable address in or related to // the memory. ffi_closure *closure = (ffi_closure *)ffi_closure_alloc(sizeof(ffi_closure), &resultFunction); if (closure == 0) raise_exception_string(taskData, EXC_foreign, "Callbacks not implemented or insufficient memory"); PLocker pLocker(&callbackTableLock); // Find a free entry in the table if there is one. unsigned entryNo = 0; while (entryNo < callBackEntries && callbackTable[entryNo].closureSpace != 0) entryNo++; if (entryNo == callBackEntries) { // Need to grow the table. struct _cbStructEntry *newTable = (struct _cbStructEntry*)realloc(callbackTable, (callBackEntries+1)*sizeof(struct _cbStructEntry)); if (newTable == 0) raise_exception_string(taskData, EXC_foreign, "Unable to allocate memory for callback table"); callbackTable = newTable; callBackEntries++; } callbackTable[entryNo].mlFunction = mlFunction->Word(); callbackTable[entryNo].closureSpace = closure; callbackTable[entryNo].resultFunction = resultFunction; if (ffi_prep_closure_loc(closure, cif, callbackEntryPt, (void*)((uintptr_t)entryNo), resultFunction) != FFI_OK) raise_exception_string(taskData, EXC_foreign,"libffi error: ffi_prep_closure_loc failed"); return toSysWord(taskData, resultFunction); } case 58: // Free an existing callback. { // The address returned from call 57 above is the executable address that can // be passed as a callback function. The writable memory address returned // as the result of ffi_closure_alloc may or may not be the same. To be safe // we need to search the table. void *resFun = *(void**)args->Word().AsAddress(); PLocker pLocker(&callbackTableLock); unsigned i = 0; while (i < callBackEntries) { if (callbackTable[i].resultFunction == resFun) { ffi_closure_free(callbackTable[i].closureSpace); callbackTable[i].closureSpace = 0; callbackTable[i].resultFunction = 0; callbackTable[i].mlFunction = TAGGED(0); // Release the ML function return taskData->saveVec.push(TAGGED(0)); } } raise_exception_string(taskData, EXC_foreign, "Invalid callback entry"); } default: { char msg[100]; sprintf(msg, "Unknown ffi function: %d", c); raise_exception_string(taskData, EXC_foreign, msg); return 0; } } }
// // Load persisted scope info. // void ScopeInfo::GetScopeInfo(Parser *parser, ByteCodeGenerator* byteCodeGenerator, FuncInfo* funcInfo, Scope* scope) { ScriptContext* scriptContext; ArenaAllocator* alloc; // Load scope attributes and push onto scope stack. scope->SetIsDynamic(this->isDynamic); if (this->isObject) { scope->SetIsObject(); } scope->SetMustInstantiate(this->mustInstantiate); if (!this->GetCanMergeWithBodyScope()) { scope->SetCannotMergeWithBodyScope(); } scope->SetHasOwnLocalInClosure(this->hasLocalInClosure); if (parser) { scriptContext = parser->GetScriptContext(); alloc = parser->GetAllocator(); } else { TRACE_BYTECODE(_u("\nRestore ScopeInfo: %s #symbols: %d %s\n"), funcInfo->name, symbolCount, isObject ? _u("isObject") : _u("")); Assert(!this->isCached || scope == funcInfo->GetBodyScope()); funcInfo->SetHasCachedScope(this->isCached); byteCodeGenerator->PushScope(scope); // The scope is already populated, so we're done. return; } // Load scope symbols // On first access to the scopeinfo, replace the ID's with PropertyRecord*'s to save the dictionary lookup // on later accesses. Replace them all before allocating Symbol's to prevent inconsistency on OOM. if (!this->areNamesCached && !PHASE_OFF1(Js::CacheScopeInfoNamesPhase)) { for (int i = 0; i < symbolCount; i++) { PropertyId propertyId = GetSymbolId(i); if (propertyId != 0) // There may be empty slots, e.g. "arguments" may have no slot { PropertyRecord const* name = scriptContext->GetPropertyName(propertyId); this->SetPropertyName(i, name); } } this->areNamesCached = true; } for (int i = 0; i < symbolCount; i++) { PropertyRecord const* name = nullptr; if (this->areNamesCached) { name = this->GetPropertyName(i); } else { PropertyId propertyId = GetSymbolId(i); if (propertyId != 0) // There may be empty slots, e.g. "arguments" may have no slot { name = scriptContext->GetPropertyName(propertyId); } } if (name != nullptr) { SymbolType symbolType = GetSymbolType(i); SymbolName symName(name->GetBuffer(), name->GetLength()); Symbol *sym = Anew(alloc, Symbol, symName, nullptr, symbolType); sym->SetScopeSlot(static_cast<PropertyId>(i)); sym->SetIsBlockVar(GetIsBlockVariable(i)); if (GetHasFuncAssignment(i)) { sym->RestoreHasFuncAssignment(); } scope->AddNewSymbol(sym); if (parser) { parser->RestorePidRefForSym(sym); } TRACE_BYTECODE(_u("%12s %d\n"), sym->GetName().GetBuffer(), sym->GetScopeSlot()); } } this->scope = scope; DebugOnly(scope->isRestored = true); }
/* evaluate Task */ static void eval(Task *task) { Symbol *s; pmValueSet *vset; int i; /* fetch metrics */ taskFetch(task); /* evaluate rule expressions */ s = task->rules; for (i = 0; i < task->nrules; i++) { curr = symValue(*s); if (curr->op < NOP) { (curr->eval)(curr); perf->eval_actual++; } s++; } if (verbose) { /* send binary values */ if (agent) { int sts; s = task->rules; for (i = 0; i < task->nrules; i++) { vset = task->rslt->vset[i]; fillVSet(symValue(*s), vset); s++; } __pmOverrideLastFd(PDU_OVERRIDE2); sts = __pmSendResult(STDOUT_FILENO, pmWhichContext(), task->rslt); if (sts < 0) { fprintf(stderr, "Error: __pmSendResult to summary agent failed: %s\n", pmErrStr(sts)); exit(0); } } /* send values to applet */ else if (applet) { s = task->rules; for (i = 0; i < task->nrules; i++) { showValue(stdout, symValue(*s)); putchar(' '); s++; } putchar('\n'); } /* print values in ASCII */ else { s = task->rules; for (i = 0; i < task->nrules; i++) { printf("%s", symName(*s)); if (archives || showTimeFlag) { printf(" ("); showTime(stdout, now); putchar(')'); } printf(": "); switch (verbose) { case 1: showValue(stdout, symValue(*s)); break; case 2: showAnnotatedValue(stdout, symValue(*s)); break; case 3: showSatisfyingValue(stdout, symValue(*s)); break; } putchar('\n'); s++; } putchar('\n'); } } }
/* reinitialize Metric - only for live host */ int /* 1: ok, 0: try again later, -1: fail */ reinitMetric(Metric *m) { char *hname = symName(m->hname); char *mname = symName(m->mname); char **inames; int *iids; int handle; int ret = 1; int sts; int i, j; /* set up temporary context */ if ((handle = newContext(hname)) < 0) return 0; host_state_changed(hname, STATE_RECONN); if ((sts = pmLookupName(1, &mname, &m->desc.pmid)) < 0) { ret = 0; goto end; } /* fill in performance metric descriptor */ if ((sts = pmLookupDesc(m->desc.pmid, &m->desc)) < 0) { ret = 0; goto end; } if (m->desc.type == PM_TYPE_STRING || m->desc.type == PM_TYPE_AGGREGATE || m->desc.type == PM_TYPE_AGGREGATE_STATIC || m->desc.type == PM_TYPE_EVENT || m->desc.type == PM_TYPE_HIGHRES_EVENT || m->desc.type == PM_TYPE_UNKNOWN) { fprintf(stderr, "%s: metric %s has non-numeric type\n", pmProgname, mname); ret = -1; } else if (m->desc.indom == PM_INDOM_NULL) { if (m->specinst != 0) { fprintf(stderr, "%s: metric %s has no instances\n", pmProgname, mname); ret = -1; } else m->m_idom = 1; } else { if ((sts = pmGetInDom(m->desc.indom, &iids, &inames)) < 0) { /* full profile */ ret = 0; } else { if (m->specinst == 0) { /* all instances */ m->iids = iids; m->m_idom = sts; m->inames = alloc(m->m_idom*sizeof(char *)); for (i = 0; i < m->m_idom; i++) { m->inames[i] = sdup(inames[i]); } } else { /* explicit instance profile */ m->m_idom = 0; for (i = 0; i < m->specinst; i++) { /* look for first matching instance name */ for (j = 0; j < sts; j++) { if (eqinst(m->inames[i], inames[j])) { m->iids[i] = iids[j]; m->m_idom++; break; } } if (j == sts) { m->iids[i] = PM_IN_NULL; ret = 0; } } if (sts > 0) { /* * pmGetInDom or pmGetInDomArchive returned some * instances above */ free(iids); } /* * if specinst != m_idom, then some not found ... move these * to the end of the list */ for (j = m->specinst-1; j >= 0; j--) { if (m->iids[j] != PM_IN_NULL) break; } for (i = 0; i < j; i++) { if (m->iids[i] == PM_IN_NULL) { /* need to swap */ char *tp; tp = m->inames[i]; m->inames[i] = m->inames[j]; m->iids[i] = m->iids[j]; m->inames[j] = tp; m->iids[j] = PM_IN_NULL; j--; } } } #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL1) { int numinst; fprintf(stderr, "reinitMetric: %s from %s: instance domain specinst=%d\n", mname, hname, m->specinst); if (m->m_idom < 1) fprintf(stderr, " %d instances!\n", m->m_idom); if (m->specinst == 0) numinst = m->m_idom; else numinst = m->specinst; for (i = 0; i < numinst; i++) { fprintf(stderr, " indom[%d]", i); if (m->iids[i] == PM_IN_NULL) fprintf(stderr, " ?missing"); else fprintf(stderr, " %d", m->iids[i]); fprintf(stderr, " \"%s\"\n", m->inames[i]); } } #endif if (sts > 0) { /* * pmGetInDom or pmGetInDomArchive returned some instances * above */ free(inames); } } } if (ret == 1) { /* compute conversion factor into canonical units - non-zero conversion factor flags initialized metric */ m->conv = scale(m->desc.units); /* automatic rate computation */ if (m->desc.sem == PM_SEM_COUNTER) { m->vals = (double *) ralloc(m->vals, m->m_idom * sizeof(double)); for (j = 0; j < m->m_idom; j++) m->vals[j] = 0; } } if (ret >= 0) { /* * re-shape, starting here are working up the expression until * we reach the top of the tree or the designated metrics * associated with the node are not the same */ Expr *x = m->expr; while (x) { /* * only re-shape expressions that may have set values */ if (x->op == CND_FETCH || x->op == CND_NEG || x->op == CND_ADD || x->op == CND_SUB || x->op == CND_MUL || x->op == CND_DIV || x->op == CND_SUM_HOST || x->op == CND_SUM_INST || x->op == CND_SUM_TIME || x->op == CND_AVG_HOST || x->op == CND_AVG_INST || x->op == CND_AVG_TIME || x->op == CND_MAX_HOST || x->op == CND_MAX_INST || x->op == CND_MAX_TIME || x->op == CND_MIN_HOST || x->op == CND_MIN_INST || x->op == CND_MIN_TIME || x->op == CND_EQ || x->op == CND_NEQ || x->op == CND_LT || x->op == CND_LTE || x->op == CND_GT || x->op == CND_GTE || x->op == CND_NOT || x->op == CND_AND || x->op == CND_OR || x->op == CND_RISE || x->op == CND_FALL || x->op == CND_INSTANT || x->op == CND_MATCH || x->op == CND_NOMATCH) { instFetchExpr(x); findEval(x); #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL1) { fprintf(stderr, "reinitMetric: re-shaped ...\n"); dumpExpr(x); } #endif } if (x->parent) { x = x->parent; if (x->metrics == m) continue; } break; } } end: /* destroy temporary context */ pmDestroyContext(handle); return ret; }
/* initialize Metric */ int /* 1: ok, 0: try again later, -1: fail */ initMetric(Metric *m) { char *hname = symName(m->hname); char *mname = symName(m->mname); char **inames; int *iids; int handle; int ret = 1; int sts; int i, j; /* set up temporary context */ if ((handle = newContext(hname)) < 0) return 0; host_state_changed(hname, STATE_RECONN); if ((sts = pmLookupName(1, &mname, &m->desc.pmid)) < 0) { fprintf(stderr, "%s: metric %s not in namespace for %s\n" "pmLookupName failed: %s\n", pmProgname, mname, findsource(hname), pmErrStr(sts)); ret = 0; goto end; } /* fill in performance metric descriptor */ if ((sts = pmLookupDesc(m->desc.pmid, &m->desc)) < 0) { fprintf(stderr, "%s: metric %s not currently available from %s\n" "pmLookupDesc failed: %s\n", pmProgname, mname, findsource(hname), pmErrStr(sts)); ret = 0; goto end; } if (m->desc.type == PM_TYPE_STRING || m->desc.type == PM_TYPE_AGGREGATE || m->desc.type == PM_TYPE_AGGREGATE_STATIC || m->desc.type == PM_TYPE_EVENT || m->desc.type == PM_TYPE_HIGHRES_EVENT || m->desc.type == PM_TYPE_UNKNOWN) { fprintf(stderr, "%s: metric %s has non-numeric type\n", pmProgname, mname); ret = -1; } else if (m->desc.indom == PM_INDOM_NULL) { if (m->specinst != 0) { fprintf(stderr, "%s: metric %s has no instances\n", pmProgname, mname); ret = -1; } else m->m_idom = 1; } else { /* metric has instances, get full instance profile */ if (archives) { if ((sts = pmGetInDomArchive(m->desc.indom, &iids, &inames)) < 0) { fprintf(stderr, "Metric %s from %s - instance domain not " "available in archive\npmGetInDomArchive failed: %s\n", mname, findsource(hname), pmErrStr(sts)); ret = -1; } } else if ((sts = pmGetInDom(m->desc.indom, &iids, &inames)) < 0) { fprintf(stderr, "Instance domain for metric %s from %s not (currently) available\n" "pmGetIndom failed: %s\n", mname, findsource(hname), pmErrStr(sts)); ret = 0; } if (ret == 1) { /* got instance profile */ if (m->specinst == 0) { /* all instances */ m->iids = iids; m->m_idom = sts; m->inames = alloc(m->m_idom*sizeof(char *)); for (i = 0; i < m->m_idom; i++) { m->inames[i] = sdup(inames[i]); } } else { /* selected instances only */ m->m_idom = 0; for (i = 0; i < m->specinst; i++) { /* look for first matching instance name */ for (j = 0; j < sts; j++) { if (eqinst(m->inames[i], inames[j])) { m->iids[i] = iids[j]; m->m_idom++; break; } } if (j == sts) { __pmNotifyErr(LOG_ERR, "metric %s from %s does not " "(currently) have instance \"%s\"\n", mname, findsource(hname), m->inames[i]); m->iids[i] = PM_IN_NULL; ret = 0; } } if (sts > 0) { /* * pmGetInDom or pmGetInDomArchive returned some * instances above */ free(iids); } /* * if specinst != m_idom, then some not found ... move these * to the end of the list */ for (j = m->specinst-1; j >= 0; j--) { if (m->iids[j] != PM_IN_NULL) break; } for (i = 0; i < j; i++) { if (m->iids[i] == PM_IN_NULL) { /* need to swap */ char *tp; tp = m->inames[i]; m->inames[i] = m->inames[j]; m->iids[i] = m->iids[j]; m->inames[j] = tp; m->iids[j] = PM_IN_NULL; j--; } } } #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL1) { int numinst; fprintf(stderr, "initMetric: %s from %s: instance domain specinst=%d\n", mname, hname, m->specinst); if (m->m_idom < 1) fprintf(stderr, " %d instances!\n", m->m_idom); numinst = m->specinst == 0 ? m->m_idom : m->specinst; for (i = 0; i < numinst; i++) { fprintf(stderr, " indom[%d]", i); if (m->iids[i] == PM_IN_NULL) fprintf(stderr, " ?missing"); else fprintf(stderr, " %d", m->iids[i]); fprintf(stderr, " \"%s\"\n", m->inames[i]); } } #endif if (sts > 0) { /* * pmGetInDom or pmGetInDomArchive returned some instances * above */ free(inames); } } } if (ret == 1) { /* compute conversion factor into canonical units - non-zero conversion factor flags initialized metric */ m->conv = scale(m->desc.units); /* automatic rate computation */ if (m->desc.sem == PM_SEM_COUNTER) { m->vals = (double *) ralloc(m->vals, m->m_idom * sizeof(double)); for (j = 0; j < m->m_idom; j++) m->vals[j] = 0; } } end: /* destroy temporary context */ pmDestroyContext(handle); /* retry not meaningful for archives */ if (archives && (ret == 0)) ret = -1; return ret; }
/* find Fetch bundle for Metric */ static Fetch * findFetch(Host *h, Metric *m) { Fetch *f; int sts; int i; int n; pmID pmid = m->desc.pmid; pmID *p; struct timeval tv; /* find existing Fetch bundle */ f = h->fetches; /* create new Fetch bundle */ if (! f) { f = newFetch(h); if ((f->handle = newContext(symName(h->name))) < 0) { free(f); h->down = 1; return NULL; } if (archives) { int tmp_ival; int tmp_mode = PM_MODE_INTERP; getDoubleAsXTB(&h->task->delta, &tmp_ival, &tmp_mode); __pmtimevalFromReal(start, &tv); if ((sts = pmSetMode(tmp_mode, &tv, tmp_ival)) < 0) { fprintf(stderr, "%s: pmSetMode failed: %s\n", pmProgname, pmErrStr(sts)); exit(1); } #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL1) { fprintf(stderr, "findFetch: fetch=0x%p host=0x%p delta=%.6f handle=%d\n", f, h, h->task->delta, f->handle); } #endif } f->next = NULL; f->prev = NULL; h->fetches = f; } /* look for existing pmid */ p = f->pmids; n = f->npmids; for (i = 0; i < n; i++) { if (*p == pmid) break; p++; } /* add new pmid */ if (i == n) { p = f->pmids; p = ralloc(p, (n+1) * sizeof(pmID)); p[n] = pmid; f->npmids = n + 1; f->pmids = p; } return f; }
/* execute fetches for given Task */ void taskFetch(Task *t) { Host *h; Fetch *f; Profile *p; Metric *m; pmResult *r; pmValueSet **v; int i; int sts; /* do all fetches, quick as you can */ h = t->hosts; while (h) { f = h->fetches; while (f) { if (f->result) pmFreeResult(f->result); if (! h->down) { pmUseContext(f->handle); if ((sts = pmFetch(f->npmids, f->pmids, &f->result)) < 0) { if (! archives) { __pmNotifyErr(LOG_ERR, "pmFetch from %s failed: %s\n", symName(f->host->name), pmErrStr(sts)); host_state_changed(symName(f->host->name), STATE_LOSTCONN); h->down = 1; mark_all(h); } f->result = NULL; } } else f->result = NULL; f = f->next; } h = h->next; } /* sort and distribute pmValueSets to requesting Metrics */ h = t->hosts; while (h) { if (! h->down) { f = h->fetches; while (f && (r = f->result)) { /* sort all vlists in result r */ v = r->vset; for (i = 0; i < r->numpmid; i++) { if ((*v)->numval > 0) { qsort((*v)->vlist, (size_t)(*v)->numval, sizeof(pmValue), compair); } v++; } /* distribute pmValueSets to Metrics */ p = f->profiles; while (p) { m = p->metrics; while (m) { for (i = 0; i < r->numpmid; i++) { if (m->desc.pmid == r->vset[i]->pmid) { if (r->vset[i]->numval > 0) { m->vset = r->vset[i]; m->stamp = __pmtimevalToReal(&r->timestamp); } break; } } m = m->next; } p = p->next; } f = f->next; } } h = h->next; } }