extern jlib_decl size32_t checked_read(int file, void *buffer, size32_t len) { if (0==len) return 0; unsigned attempts = 0; size32_t ret = 0; unsigned __int64 startCycles = get_cycles_now(); loop { ssize_t readNow = _read(file, buffer, len); if (readNow == (ssize_t)-1) { switch (errno) { case EINTR: readNow = 0; break; default: if (attempts < ioRetryCount) { attempts++; StringBuffer callStr("read"); callStr.append("[errno=").append(errno); unsigned __int64 elapsedMs = cycle_to_nanosec(get_cycles_now() - startCycles)/1000000; callStr.append(", took=").append(elapsedMs); callStr.append(", attempt=").append(attempts).append("](handle="); callStr.append(file).append(", len=").append(len).append(")"); PROGLOG("%s", callStr.str()); readNow = 0; break; } throw makeErrnoException(errno, "checked_read"); } } else if (!readNow) break; ret += readNow; if (readNow == (ssize_t)len) break; buffer = ((char *) buffer) + readNow; len -= readNow; } return ret; }
extern jlib_decl size32_t checked_pread(int file, void *buffer, size32_t len, offset_t pos) { if (0==len) return 0; #ifdef WIN32 if (atomicsupported) { HANDLE hFile = (HANDLE)_get_osfhandle(file); DWORD rread; OVERLAPPED overlapped; memset(&overlapped, 0, sizeof(overlapped)); overlapped.Offset = (DWORD) pos; overlapped.OffsetHigh = (DWORD)(pos>>32); if (ReadFile(hFile, buffer, len, &rread, &overlapped)) return rread; int err = (int)GetLastError(); if (err == ERROR_HANDLE_EOF) return 0; if (err == ERROR_INVALID_PARAMETER) // Win98 etc atomicsupported = false; else throw makeOsException(GetLastError(), "checked_pread"); } { CriticalBlock blk(atomicsection); checked_lseeki64(file, pos, FILE_BEGIN); return checked_read(file, buffer, len); } #else size32_t ret = 0; unsigned attempts = 0; unsigned __int64 startCycles = get_cycles_now(); loop { ssize_t readNow = ::pread(file, buffer, len, pos); if (readNow == (ssize_t)-1) { switch (errno) { case EINTR: readNow = 0; break; default: if (attempts < ioRetryCount) { attempts++; StringBuffer callStr("pread"); callStr.append("[errno=").append(errno); unsigned __int64 elapsedMs = cycle_to_nanosec(get_cycles_now() - startCycles)/1000000; callStr.append(", took=").append(elapsedMs); callStr.append(", attempt=").append(attempts).append("](handle="); callStr.append(file).append(", pos=").append(pos).append(", len=").append(len).append(")"); PROGLOG("%s", callStr.str()); readNow = 0; break; } throw makeErrnoException(errno, "checked_pread"); } } else if (!readNow) break; ret += readNow; if (readNow == (ssize_t)len) break; pos += readNow; buffer = ((char *) buffer) + readNow; len -= readNow; } return ret; #endif }
bool compile(const char *wuid, const char *target, const char *targetCluster) { Owned<IConstWUQuery> query = workunit->getQuery(); if (!query) { reportError("Workunit does not contain a query", 2); return false; } addTimeStamp(workunit, SSTglobal, NULL, StWhenCompiled); SCMStringBuffer mainDefinition; SCMStringBuffer eclQuery; query->getQueryText(eclQuery); query->getQueryMainDefinition(mainDefinition); StringBuffer eclccProgName; splitDirTail(queryCurrentProcessPath(), eclccProgName); eclccProgName.append("eclcc"); StringBuffer eclccCmd(" -shared"); if (eclQuery.length()) eclccCmd.append(" -"); if (mainDefinition.length()) eclccCmd.append(" -main ").append(mainDefinition); eclccCmd.append(" --timings --xml"); eclccCmd.append(" --nostdinc"); if (globals->getPropBool("@enableEclccDali", true)) { const char *daliServers = globals->queryProp("@daliServers"); if (!daliServers) daliServers = "."; eclccCmd.appendf(" -dfs=%s", daliServers); const char *wuScope = workunit->queryWuScope(); if (!isEmptyString(wuScope)) eclccCmd.appendf(" -scope=%s", wuScope); eclccCmd.appendf(" -cluster=%s", targetCluster); SCMStringBuffer token; workunit->getSecurityToken(token); if (token.length()) eclccCmd.appendf(" -wuid=%s -token=%s", workunit->queryWuid(), token.str()); } Owned<IPipeProcess> pipe = createPipeProcess(); pipe->setenv("ECLCCSERVER_THREAD_INDEX", idxStr.str()); Owned<IPropertyTreeIterator> options = globals->getElements("./Option"); ForEach(*options) { IPropertyTree &option = options->query(); const char *name = option.queryProp("@name"); const char *value = option.queryProp("@value"); const char *cluster = option.queryProp("@cluster"); // if cluster is set it's specific to a particular target if (name && (cluster==NULL || cluster[0]==0 || strcmp(cluster, targetCluster)==0)) processOption(name, value, eclccCmd, eclccProgName, *pipe, false); } eclccCmd.appendf(" -o%s", wuid); eclccCmd.appendf(" -platform=%s", target); eclccCmd.appendf(" --component=%s", queryStatisticsComponentName()); Owned<IStringIterator> debugValues = &workunit->getDebugValues(); ForEach (*debugValues) { SCMStringBuffer debugStr, valueStr; debugValues->str(debugStr); workunit->getDebugValue(debugStr.str(), valueStr); processOption(debugStr.str(), valueStr.str(), eclccCmd, eclccProgName, *pipe, true); } if (workunit->getResultLimit()) { eclccCmd.appendf(" -fapplyInstantEclTransformations=1 -fapplyInstantEclTransformationsLimit=%u", workunit->getResultLimit()); } try { cycle_t startCycles = get_cycles_now(); Owned<ErrorReader> errorReader = new ErrorReader(pipe, this); Owned<AbortWaiter> abortWaiter = new AbortWaiter(pipe, workunit); eclccCmd.insert(0, eclccProgName); if (!pipe->run(eclccProgName, eclccCmd, ".", true, false, true, 0, true)) throw makeStringExceptionV(999, "Failed to run eclcc command %s", eclccCmd.str()); errorReader->start(); abortWaiter->start(); try { pipe->write(eclQuery.s.length(), eclQuery.s.str()); pipe->closeInput(); } catch (IException *e) { reportError(e); e->Release(); } unsigned retcode = pipe->wait(); errorReader->join(); abortWaiter->stop(); if (retcode == 0) { StringBuffer realdllname, dllurl; realdllname.append(SharedObjectPrefix).append(wuid).append(SharedObjectExtension); StringBuffer realdllfilename(dllPath); realdllfilename.append(SharedObjectPrefix).append(wuid).append(SharedObjectExtension); StringBuffer wuXML; if (!getWorkunitXMLFromFile(realdllfilename, wuXML)) throw makeStringException(999, "Failed to extract workunit from query dll"); Owned<ILocalWorkUnit> embeddedWU = createLocalWorkUnit(wuXML); queryExtendedWU(workunit)->copyWorkUnit(embeddedWU, false, true); workunit->setIsClone(false); const char *jobname = embeddedWU->queryJobName(); if (jobname && *jobname) //let ECL win naming job during initial compile workunit->setJobName(jobname); if (!workunit->getDebugValueBool("obfuscateOutput", false)) { Owned<IWUQuery> query = workunit->updateQuery(); query->setQueryText(eclQuery.s.str()); } createUNCFilename(realdllfilename.str(), dllurl); unsigned crc = crc_file(realdllfilename.str()); Owned<IWUQuery> query = workunit->updateQuery(); associateLocalFile(query, FileTypeDll, realdllfilename, "Workunit DLL", crc); queryDllServer().registerDll(realdllname.str(), "Workunit DLL", dllurl.str()); cycle_t elapsedCycles = get_cycles_now() - startCycles; updateWorkunitTimeStat(workunit, SSTcompilestage, "compile", StTimeElapsed, NULL, cycle_to_nanosec(elapsedCycles)); workunit->commit(); return true; } } catch (IException * e) { reportError(e); e->Release(); } return false; }
inline unsigned __int64 elapsedNs() const { return cycle_to_nanosec(elapsedCycles()); }
// Return the total amount of time (in nanoseconds) spent in the first call of this activity (first entry to first exit) inline unsigned __int64 latency() const { return cycle_to_nanosec(latencyCycles()); }
// Return the total amount of time (in nanoseconds) spent in this activity (first entry to last exit) inline unsigned __int64 elapsed() const { return cycle_to_nanosec(endCycles-startCycles); }
inline unsigned elapsedMs() { return cycle_to_nanosec(elapsedCycles())/1000000; }