void CliGlobals::init( NABoolean espProcess, StatsGlobals *statsGlobals ) { int threadCount = NAAssertMutexCreate(); if (threadCount != 1) // The main executor thread must be first abort(); SQLMXLoggingArea::init(); #if !(defined(__SSCP) || defined(__SSMP)) sharedCtrl_ = new(&executorMemory_) ExControlArea(NULL /*context */, &executorMemory_); #else sharedCtrl_ = NULL; #endif char *_sqptr = 0; _sqptr = new (&executorMemory_) char[10]; numCliCalls_ = 0; logEmsEvents_ = TRUE; nodeName_[0] = '\0'; breakEnabled_ = FALSE; SPBreakReceived_ = FALSE; isESPProcess_ = FALSE; logReclaimEventDone_ = FALSE; // find and initialize the directory this program is being run from. // Max length of oss dirname is 1K (process_getinfolist_ limit). // Also initialize the node, cpu and pin my process is running at. programDir_ = new (&executorMemory_) char[1024 + 1]; short nodeNameLen; Lng32 retcomrt = 0; retcomrt = ComRtGetProgramInfo(programDir_, 1024, processType_, myCpu_, myPin_, myNodeNumber_, myNodeName_, nodeNameLen, myStartTime_, myProcessNameString_, parentProcessNameString_ #ifdef SQ_PHANDLE_VERIFIER , &myVerifier_ #endif ); if (retcomrt) { char errStr[128];//LCOV_EXCL_LINE sprintf (errStr, "Could not initialize CLI globals.ComRtGetProgramInfo returned an error :%d.", retcomrt);//LCOV_EXCL_LINE ex_assert(0,errStr);//LCOV_EXCL_LINE } ComRtGetProcessPriority(myPriority_); savedPriority_ = (short)myPriority_; myNumSegs_ = 0; myNumCpus_ = 0; SEGMENT_INFO * segs = new(&executorMemory_) SEGMENT_INFO[MAX_NO_OF_SEGMENTS]; ComRtGetSegsInfo(segs, MAX_NO_OF_SEGMENTS, myNumSegs_, (NAHeap *)&executorMemory_); for (Lng32 i = 0; i < myNumSegs_; i++) { myNumCpus_ += segs[i].noOfCpus_; } NADELETEARRAY(segs, MAX_NO_OF_SEGMENTS, SEGMENT_INFO, &executorMemory_); // create global structures for IPC environment #if !(defined(__SSCP) || defined(__SSMP)) // check if Measure is enabled and allocate Measure process counters. measProcCntrs_ = NULL; measProcEnabled_ = 0; measStmtEnabled_ = 0; measSubsysRunning_ = 0; measProcCntrs_ = new(&executorMemory_) ExMeasProcCntrs(); // Ask Measure for status ExMeasGetStatus( measStmtEnabled_, measProcEnabled_, measSubsysRunning_ ); if (measProcEnabled_) { //ss_cc_change This will not get hit on seaquest //LCOV_EXCL_START Int32 measError = measProcCntrs_->ExMeasProcCntrsBump(); if (measError) { NADELETEBASIC (measProcCntrs_, &executorMemory_); measProcCntrs_ = NULL; measProcEnabled_ = 0; measStmtEnabled_ = 0; } //LCOV_EXCL_STOP } ipcHeap_ = new(&executorMemory_) NAHeap("IPC Heap", NAMemory::IPC_MEMORY, 2048 * 1024); ipcHeap_->setThreadSafe(); if (! espProcess) { // Create the process global ARKCMP server. // In R1.8, Each context has its own mxcmp. sharedArkcmp_ = NULL; //sharedArkcmp_->setShared(FALSE); // create the process global memory monitor. For now with // defaults of 10 window entries and sampling every 1 second Lng32 memMonitorWindowSize = 10; Lng32 memMonitorSampleInterval = 1; // reduced from 10 (for M5 - May 2011) memMonitor_ = new(&executorMemory_) MemoryMonitor(memMonitorWindowSize, memMonitorSampleInterval, &executorMemory_); // nextUniqueContextHandle = 2000; nextUniqueContextHandle = DEFAULT_CONTEXT_HANDLE; arlibHeap_ = new (&executorMemory_) NAHeap("MXARLIB Cache Heap", &executorMemory_, (Lng32) 32768); lastUniqueNumber_ = 0; sessionUniqueNumber_ = 0; // It is not thread safe to set the globals cli_globals // before cli_globals is fully initialized, but it is being done // here because the code below expects it cli_globals = this; short error; statsGlobals_ = (StatsGlobals *)shareStatsSegment(shmId_); if (statsGlobals_ == NULL || (statsGlobals_ != NULL && statsGlobals_->getVersion() != StatsGlobals::CURRENT_SHARED_OBJECTS_VERSION_)) { statsGlobals_ = NULL; statsHeap_ = new (getExecutorMemory()) NAHeap("Process Stats Heap", getExecutorMemory(), 8192, 0); statsHeap_->setThreadSafe(); } else { error = statsGlobals_->openStatsSemaphore(semId_); // Behave like as if stats is not available //ss_cc_change - rare error case //LCOV_EXCL_START if (error != 0) { statsGlobals_ = NULL; statsHeap_ = getExecutorMemory(); } //LCOV_EXCL_STOP else { short savedPriority, savedStopMode; error = statsGlobals_->getStatsSemaphore(semId_, myPin_, savedPriority, savedStopMode, FALSE /*shouldTimeout*/); ex_assert(error == 0, "getStatsSemaphore() returned an error"); statsHeap_ = (NAHeap *)statsGlobals_-> getStatsHeap()->allocateHeapMemory(sizeof *statsHeap_, FALSE); // The following assertion may be hit if the RTS shared memory // segment is full. The stop catcher code will be responsible // for releasing the RTS semaphore. ex_assert(statsHeap_, "allocateHeapMemory returned NULL."); // This next allocation, a placement "new" will not fail. statsHeap_ = new (statsHeap_, statsGlobals_->getStatsHeap()) NAHeap("Process Stats Heap", statsGlobals_->getStatsHeap(), 8192, 0); statsGlobals_->addProcess(myPin_, statsHeap_); processStats_ = statsGlobals_->getExProcessStats(myPin_); processStats_->setStartTime(myStartTime_); statsGlobals_->releaseStatsSemaphore(semId_, myPin_, savedPriority, savedStopMode); } } // create a default context and make it the current context cliSemaphore_ = new (&executorMemory_) CLISemaphore(); defaultContext_ = new (&executorMemory_) ContextCli(this); contextList_ = new(&executorMemory_) HashQueue(&executorMemory_); tidList_ = new(&executorMemory_) HashQueue(&executorMemory_); SQLCTX_HANDLE ch = defaultContext_->getContextHandle(); contextList_->insert((char*)&ch, sizeof(SQLCTX_HANDLE), (void*)defaultContext_); qualifyingVolsPerNode_.setHeap(defaultContext_->exCollHeap()); cpuNumbers_.setHeap(defaultContext_->exCollHeap()); capacities_.setHeap(defaultContext_->exCollHeap()); freespaces_.setHeap(defaultContext_->exCollHeap()); largestFragments_.setHeap(defaultContext_->exCollHeap()); } // (!espProcess) else { // For ESPs do not create the default context here. At this point // the ESP has not created an IpcEnvironment object yet so the // result context will have an invalid ExSqlComp object that // points to a NULL IpcEnvironment. In bin/ex_esp_main.cpp, the // following objects are created at ESP startup time: // - CliGlobals // - IpcEnvironment // - Default ContextCli in CliGlobals // - MemoryMonitor // - ExEspFragInstanceDir // - ExEspControl Message // - Global UDR server manager cliSemaphore_ = new (&executorMemory_) CLISemaphore(); statsGlobals_ = NULL; semId_ = -1; statsHeap_ = NULL; lastUniqueNumber_ = 0; } // if (!espProcess) else ... #else // (defined(__SSCP) || defined(__SSMP)) cliSemaphore_ = new (&executorMemory_) CLISemaphore(); statsGlobals_ = statsGlobals; semId_ = -1; statsHeap_ = NULL; lastUniqueNumber_ = 0; #endif inConstructor_ = FALSE; // // could initialize the program file name here but ... myProgName_[0] = '\0'; }
Int32 runESP(Int32 argc, char** argv, GuaReceiveFastStart *guaReceiveFastStart) { // initialize ESP global data StatsGlobals * statsGlobals; XCONTROLMESSAGESYSTEM(XCTLMSGSYS_SETRECVLIMIT, XMAX_SETTABLE_RECVLIMIT_H); CliGlobals *cliGlobals = NULL; cliGlobals = CliGlobals::createCliGlobals(TRUE); // TRUE indicates a non-master process (WAIT on LREC) if (cliGlobals == NULL) // Sanity check NAExit(1); // Abend Int32 shmid; statsGlobals = shareStatsSegment(shmid); cliGlobals->setSharedMemId(shmid); //Lng32 numCliCalls = cliGlobals->incrNumOfCliCalls(); cliGlobals->setIsESPProcess(TRUE); NAHeap *espExecutorHeap = cliGlobals->getExecutorMemory(); // must create default context after set IpcEnvironment in CliGlobals first // because context's ExSqlComp object needs IpcEnvironment cliGlobals->initiateDefaultContext(); NAHeap *espIpcHeap = cliGlobals->getIpcHeap(); IpcEnvironment *ipcEnvPtr = cliGlobals->getEnvironment(); if (statsGlobals != NULL) cliGlobals->setMemoryMonitor(statsGlobals->getMemoryMonitor()); else { // Start the memory monitor for dynamic memory management Lng32 memMonitorWindowSize = 10; Lng32 memMonitorSampleInterval = 10; MemoryMonitor *memMonitor = new (espExecutorHeap) MemoryMonitor(memMonitorWindowSize, memMonitorSampleInterval, espExecutorHeap); cliGlobals->setMemoryMonitor(memMonitor); } // After CLI globals are initialized but before we begin ESP message // processing, have the CLI context set its user identity based on // the OS user identity. ContextCli *context = cliGlobals->currContext(); ex_assert(context, "Invalid context pointer"); context->initializeUserInfoFromOS(); ExEspFragInstanceDir espFragInstanceDir(cliGlobals, espExecutorHeap, (StatsGlobals *)statsGlobals); ExEspControlMessage espIpcControlMessage(&espFragInstanceDir, ipcEnvPtr, espIpcHeap); // handle startup (command line args, control connection) DoEspStartup(argc,argv,*ipcEnvPtr,espFragInstanceDir,guaReceiveFastStart); // the control message stream talks through the control connection espIpcControlMessage.addRecipient( ipcEnvPtr->getControlConnection()->getConnection()); // start the first receive operation espIpcControlMessage.receive(FALSE); NABoolean timeout; Int64 prevWaitTime = 0; // while there are requesters while (espFragInstanceDir.getNumMasters() > 0) { // ----------------------------------------------------------------- // The ESPs most important line of code: DO THE WORK // ----------------------------------------------------------------- espFragInstanceDir.work(prevWaitTime); // ----------------------------------------------------------------- // After we have done work, it's necessary to wait for some I/O // (the frag instance dir work procedure works until it is blocked). // ----------------------------------------------------------------- ipcEnvPtr->getAllConnections()-> waitOnAll(IpcInfiniteTimeout, TRUE, &timeout, &prevWaitTime); // TRUE means: Called by ESP main } // nobody wants us anymore, right now that means that we stop return 0; }