📄 osutils.cxx
字号:
static PProcessStartupList & GetPProcessStartupList(){ static PProcessStartupList list; return list;}PProcess::PProcess(const char * manuf, const char * name, WORD major, WORD minor, CodeStatus stat, WORD build) : manufacturer(manuf), productName(name){ PProcessInstance = this; terminationValue = 0; majorVersion = major; minorVersion = minor; status = stat; buildNumber = build; // This flag must never be destroyed before it is finished with. As we // cannot assure destruction at the right time we simply allocate it and // NEVER destroy it! This is OK as the only reason for its destruction is // the program is exiting and then who cares?#if PMEMORY_CHECK BOOL ignoreAllocations = PMemoryHeap::SetIgnoreAllocations(TRUE);#endif PTraceMutex = new PMutex;#if PMEMORY_CHECK PMemoryHeap::SetIgnoreAllocations(ignoreAllocations);#endif#ifndef P_RTEMS if (p_argv != 0 && p_argc > 0) { arguments.SetArgs(p_argc-1, p_argv+1); executableFile = PString(p_argv[0]); if (!PFile::Exists(executableFile)) { PString execFile = executableFile + ".exe"; if (PFile::Exists(execFile)) executableFile = execFile; } if (productName.IsEmpty()) productName = executableFile.GetTitle().ToLower(); }#else cout << "Enter program arguments:\n"; arguments.ReadFrom(cin);#endif InitialiseProcessThread(); Construct(); #ifdef __MACOSX__ #ifdef HAS_VIDEO PWLibStupidOSXHacks::loadFakeVideoStuff = 1;#ifdef USE_SHM_VIDEO_DEVICES PWLibStupidOSXHacks::loadShmVideoStuff = 1;#endif // USE_SHM_VIDEO_DEVICES#endif // HAS_VIDEO #ifdef HAS_AUDIO PWLibStupidOSXHacks::loadCoreAudioStuff = 1;#endif // HAS_AUDIO #endif // __MACOSX__ // create one instance of each class registered in the // PProcessStartup abstract factory PProcessStartupList & startups = GetPProcessStartupList(); { PProcessStartup * levelSet = PFactory<PProcessStartup>::CreateInstance("SetTraceLevel"); if (levelSet != NULL) levelSet->OnStartup(); else { char * env = ::getenv("PWLIB_TRACE_STARTUP"); if (env != NULL) PTrace::Initialise(atoi(env), NULL, PTrace::Blocks | PTrace::Timestamp | PTrace::Thread | PTrace::FileAndLine); } PProcessStartupFactory::KeyList_T list = PProcessStartupFactory::GetKeyList(); PProcessStartupFactory::KeyList_T::const_iterator r; for (r = list.begin(); r != list.end(); ++r) { if (*r != "SetTraceLevel") { PProcessStartup * instance = PProcessStartupFactory::CreateInstance(*r); instance->OnStartup(); startups.insert(std::pair<PString, PProcessStartup *>(*r, instance)); } } }}void PProcess::PreShutdown(){ PProcessStartupList & startups = GetPProcessStartupList(); // call OnShutfdown for the PProcessInstances previously created // make sure we handle singletons correctly { while (startups.size() > 0) { PProcessStartupList::iterator r = startups.begin(); PProcessStartup * instance = r->second; instance->OnShutdown(); if (!PProcessStartupFactory::IsSingleton(r->first)) delete instance; startups.erase(r); } }}PProcess & PProcess::Current(){ if (PProcessInstance == NULL) { cerr << "Catastrophic failure, PProcess::Current() = NULL!!\n";#if defined(_MSC_VER) && defined(_DEBUG) && !defined(_WIN32_WCE) __asm int 3;#endif _exit(1); } return *PProcessInstance;}BOOL PProcess::IsInitialised(){ return PProcessInstance != NULL;}PObject::Comparison PProcess::Compare(const PObject & obj) const{ PAssert(PIsDescendant(&obj, PProcess), PInvalidCast); return productName.Compare(((const PProcess &)obj).productName);}void PProcess::Terminate(){#ifdef _WINDLL FatalExit(terminationValue);#else exit(terminationValue);#endif}PString PProcess::GetThreadName() const{ return GetName(); } void PProcess::SetThreadName(const PString & /*name*/){}PTime PProcess::GetStartTime() const{ return programStartTime; }PString PProcess::GetVersion(BOOL full) const{ const char * const statusLetter[NumCodeStatuses] = { "alpha", "beta", "." }; return psprintf(full ? "%u.%u%s%u" : "%u.%u", majorVersion, minorVersion, statusLetter[status], buildNumber);}void PProcess::SetConfigurationPath(const PString & path){ configurationPaths = path.Tokenise(";:", FALSE);}///////////////////////////////////////////////////////////////////////////////// PThreadvoid PThread::PrintOn(ostream & strm) const{ strm << GetThreadName();}PString PThread::GetThreadName() const{ return threadName; }#if defined(_MSC_VER)typedef struct tagTHREADNAME_INFO{ DWORD dwType ; // must be 0x1000 LPCSTR szName ; // pointer to name (in user addr space) DWORD dwThreadID ; // thread ID (-1=caller thread, but seems to set more than one thread's name) DWORD dwFlags ; // reserved for future use, must be zero} THREADNAME_INFO ;void SetWinDebugThreadName (THREADNAME_INFO * info){ __try { RaiseException (0x406D1388, 0, sizeof(THREADNAME_INFO)/sizeof(DWORD), (DWORD *) info) ; } // if not running under debugger exception comes back __except(EXCEPTION_CONTINUE_EXECUTION) { // just keep on truckin' }}#endifvoid PThread::SetThreadName(const PString & name){ if (name.IsEmpty()) threadName = psprintf("%s:%08x", GetClass(), (INT)this); else threadName = psprintf(name, (INT)this);#if defined(_MSC_VER) if (threadId) { // make thread name known to debugger THREADNAME_INFO Info = { 0x1000, (const char *) threadName, threadId, 0 } ; SetWinDebugThreadName (&Info) ; }#endif} PThread * PThread::Create(const PNotifier & notifier, INT parameter, AutoDeleteFlag deletion, Priority priorityLevel, const PString & threadName, PINDEX stackSize){ PThread * thread = new PSimpleThread(notifier, parameter, deletion, priorityLevel, threadName, stackSize); if (deletion != AutoDeleteThread) return thread; // Do not return a pointer to the thread if it is auto-delete as this // pointer is extremely dangerous to use, it could be deleted at any moment // from now on so using the pointer could crash the program. return NULL;}PSimpleThread::PSimpleThread(const PNotifier & notifier, INT param, AutoDeleteFlag deletion, Priority priorityLevel, const PString & threadName, PINDEX stackSize) : PThread(stackSize, deletion, priorityLevel, threadName), callback(notifier), parameter(param){ Resume();}void PSimpleThread::Main(){ callback(*this, parameter);}/////////////////////////////////////////////////////////////////////////////void PSyncPointAck::Signal(){ PSyncPoint::Signal(); ack.Wait();}void PSyncPointAck::Signal(const PTimeInterval & wait){ PSyncPoint::Signal(); ack.Wait(wait);}void PSyncPointAck::Acknowledge(){ ack.Signal();}/////////////////////////////////////////////////////////////////////////////void PCondMutex::WaitCondition(){ for (;;) { Wait(); if (Condition()) return; PMutex::Signal(); OnWait(); syncPoint.Wait(); }}void PCondMutex::Signal(){ if (Condition()) syncPoint.Signal(); PMutex::Signal();}void PCondMutex::OnWait(){ // Do nothing}/////////////////////////////////////////////////////////////////////////////PIntCondMutex::PIntCondMutex(int val, int targ, Operation op){ value = val; target = targ; operation = op;}void PIntCondMutex::PrintOn(ostream & strm) const{ strm << '(' << value; switch (operation) { case LT : strm << " < "; case LE : strm << " <= "; case GE : strm << " >= "; case GT : strm << " > "; default: strm << " == "; } strm << target << ')';}BOOL PIntCondMutex::Condition(){ switch (operation) { case LT : return value < target; case LE : return value <= target; case GE : return value >= target; case GT : return value > target; default : break; } return value == target;}PIntCondMutex & PIntCondMutex::operator=(int newval){ Wait(); value = newval; Signal(); return *this;}PIntCondMutex & PIntCondMutex::operator++(){ Wait(); value++; Signal(); return *this;}PIntCondMutex & PIntCondMutex::operator+=(int inc){ Wait(); value += inc; Signal(); return *this;}PIntCondMutex & PIntCondMutex::operator--(){ Wait(); value--; Signal(); return *this;}PIntCondMutex & PIntCondMutex::operator-=(int dec){ Wait(); value -= dec; Signal(); return *this;}/////////////////////////////////////////////////////////////////////////////PReadWriteMutex::PReadWriteMutex() : readerSemaphore(1, 1), writerSemaphore(1, 1){ readerCount = 0; writerCount = 0;}PReadWriteMutex::Nest * PReadWriteMutex::GetNest() const{ PWaitAndSignal mutex(nestingMutex); return nestedThreads.GetAt(POrdinalKey((PINDEX)PThread::GetCurrentThreadId()));}void PReadWriteMutex::EndNest(){ nestingMutex.Wait(); nestedThreads.RemoveAt(POrdinalKey((PINDEX)PThread::GetCurrentThreadId())); nestingMutex.Signal();}PReadWriteMutex::Nest & PReadWriteMutex::StartNest(){ POrdinalKey threadId = (PINDEX)PThread::GetCurrentThreadId(); nestingMutex.Wait(); Nest * nest = nestedThreads.GetAt(threadId); if (nest == NULL) { nest = new Nest; nestedThreads.SetAt(threadId, nest); } nestingMutex.Signal(); return *nest;}void PReadWriteMutex::StartRead(){ // Get the nested thread info structure, create one it it doesn't exist Nest & nest = StartNest(); // One more nested call to StartRead() by this thread, note this does not // need to be mutexed as it is always in the context of a single thread. nest.readerCount++; // If this is the first call to StartRead() and there has not been a //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -