Date: Fri, 4 Jun 2004 00:04:19 EST-10EDT,10,-1,0,7200,3,-1,0,7200,3600 Subject: [UnixOS2_Archive] No. 392 ************************************************** Thursday 03 June 2004 Number 392 ************************************************** Subjects for today 1 Os/2 Thread classes : Dave Webster 2 RE: Os/2 Thread classes : Dave Webster 3 Re: Os/2 Thread classes : Dave Yeo" 4 Re: Os/2 Thread classes : Stefan.Neis at t-online.de 1 Re: Os/2 Thread classes : Stefan.Neis at t-online.de **= Email 1 ==========================** Date: Wed, 2 Jun 2004 10:44:14 -0500 From: Dave Webster Subject: Os/2 Thread classes Stefan? Have you tested wxOS2's Thread class lately with Innotek GCC? I am continuing to have great trouble getting threads to work using _beginthread inside a Thread class (wxOS2's or my own). Everything works quite nicely in a straight 'C' program as below: #include #include #include #define INCL_BASE #include extern "C" void CntThreadProc (void* pParam); typedef struct counter_tag { ULONG ulThreadCnt; ULONG ulCurCnt; } SCounter; int main ( int vArgc , char* ppzArgv[] , char* ppzEnvp[] ) { SCounter vCounter; int nThreadId; vCounter.ulThreadCnt = 75000; vCounter.ulCurCnt = 0; nThreadId = _beginthread( CntThreadProc ,NULL ,32768 ,(void*)&vCounter ); ::DosSleep(100); ::DosSuspendThread(nThreadId); std::cout << "Thread: " << nThreadId << " Suspended for 3 seconds on count of: " << vCounter.ulCurCnt << "." << std::endl; ::DosSleep(3000); std::cout << "Thread: " << nThreadId << " Resuming now for 2 seconds." << std::endl; ::DosResumeThread(nThreadId); while (vCounter.ulCurCnt < 25000) { ::DosSleep(2000); ::DosSuspendThread(nThreadId); std::cout << "Thread: " << nThreadId << " Suspended for 2 more seconds on count of: " << vCounter.ulCurCnt << "." << std::endl; ::DosSleep(2000); std::cout << "Thread: " << nThreadId << " Resuming now for 2 seconds." << std::endl; ::DosResumeThread(nThreadId); } std::cout << "Thread: " << nThreadId << " Resuming now and waiting until done." << std::endl; ::DosWaitThread((PULONG)&nThreadId, DCWW_WAIT); ::DosSleep(2000); std::cout << "Program has finished!" << std::endl; return 0; } // end of main extern "C" void CntThreadProc ( void* pParam ) { SCounter* pCounter = (SCounter*)pParam; ULONG ulSomething = 0; for (pCounter->ulCurCnt = 0; pCounter->ulCurCnt < pCounter->ulThreadCnt; pCounter->ulCurCnt++ ) { // so we have something to do while (ulSomething < 10000) ulSomething++; ulSomething = 0; } std::cout << "2nd Thread has finished!" << std::endl; _endthread(); } However, when buried inside a thread class, the initialization function passed to _begin thread does never gets called. The thread gets created but it never calls the proc??? Below is a snippet: thread.h class CThread { public: bool ThreadCreate(); static void StartThread(void* pParam); . . . private: int m_nThreadId; } thread.cpp void StartThread(void* pParam) { do some initialization here.... . . . } bool CThread::ThreadCreate() { SStartup vStartup; // contains a pointer to this thread and other useful stuff m_nThreadId = ::_beginthread( CThread::StartThread ,NULL ,32768 ,(void*)vStartup ); if (m_nThreadId == -1) { Some sort of error reporting here... return false; } ::DosSleep(100); // let thread initialize return true; } Call to StartThread then posts a ::DosWaitThread(...) waiting for this second thread to complete and just hangs forever.... Breakpoint on the if (m_nThreadId == -1) line indicates m_nThreadId is a valid threadid. IPMD (debugger) reports that there are two threads running. But StartThread never gets called!!! It is as if _beginthread cannot find the address??? I have tried this using an extern "C" initialization proc instead of a static member proc with has the exact same results. A new thread but init function called. Anyone with any idea??? Threads via classes appear to be completely brokein with Innotek GCC at this time.... Must be missing something basic but cannot figure it out. **= Email 2 ==========================** Date: Wed, 2 Jun 2004 13:30:28 -0500 From: Dave Webster Subject: RE: Os/2 Thread classes Actually, wxOS2's works fine now. In my class however somehow my main thread has entered a critical section. So no problem related to Innotek's _beginthread implementation..... And for wxWidgets--- And this is confusing to me. The wxThreadModule (I have something very similar in my class as well) has the static global CritsecGui which gets entered OnInit and does not get exitted until OnExit. This should cause the same problem in wxOS2's threads but it doesn't???? Entering a critical section stops processing in all other threads until exitting, but the wxOS2 threads do not block when this Critsec is entered??? Must have something to do with when and how the code in wxThreadModule get executed when using wxThread. I'm really missing something here..... -----Original Message----- From: Dave Webster [mailto:Dave.Webster at bhmi.com] Sent: Wednesday, June 02, 2004 10:44 AM To: WxDiscuss (E-mail); Unix-OS2 (E-mail 2) Subject: Os/2 Thread classes Stefan? Have you tested wxOS2's Thread class lately with Innotek GCC? I am continuing to have great trouble getting threads to work using _beginthread inside a Thread class (wxOS2's or my own). Everything works quite nicely in a straight 'C' program as below: #include #include #include #define INCL_BASE #include extern "C" void CntThreadProc (void* pParam); typedef struct counter_tag { ULONG ulThreadCnt; ULONG ulCurCnt; } SCounter; int main ( int vArgc , char* ppzArgv[] , char* ppzEnvp[] ) { SCounter vCounter; int nThreadId; vCounter.ulThreadCnt = 75000; vCounter.ulCurCnt = 0; nThreadId = _beginthread( CntThreadProc ,NULL ,32768 ,(void*)&vCounter ); ::DosSleep(100); ::DosSuspendThread(nThreadId); std::cout << "Thread: " << nThreadId << " Suspended for 3 seconds on count of: " << vCounter.ulCurCnt << "." << std::endl; ::DosSleep(3000); std::cout << "Thread: " << nThreadId << " Resuming now for 2 seconds." << std::endl; ::DosResumeThread(nThreadId); while (vCounter.ulCurCnt < 25000) { ::DosSleep(2000); ::DosSuspendThread(nThreadId); std::cout << "Thread: " << nThreadId << " Suspended for 2 more seconds on count of: " << vCounter.ulCurCnt << "." << std::endl; ::DosSleep(2000); std::cout << "Thread: " << nThreadId << " Resuming now for 2 seconds." << std::endl; ::DosResumeThread(nThreadId); } std::cout << "Thread: " << nThreadId << " Resuming now and waiting until done." << std::endl; ::DosWaitThread((PULONG)&nThreadId, DCWW_WAIT); ::DosSleep(2000); std::cout << "Program has finished!" << std::endl; return 0; } // end of main extern "C" void CntThreadProc ( void* pParam ) { SCounter* pCounter = (SCounter*)pParam; ULONG ulSomething = 0; for (pCounter->ulCurCnt = 0; pCounter->ulCurCnt < pCounter->ulThreadCnt; pCounter->ulCurCnt++ ) { // so we have something to do while (ulSomething < 10000) ulSomething++; ulSomething = 0; } std::cout << "2nd Thread has finished!" << std::endl; _endthread(); } However, when buried inside a thread class, the initialization function passed to _begin thread does never gets called. The thread gets created but it never calls the proc??? Below is a snippet: thread.h class CThread { public: bool ThreadCreate(); static void StartThread(void* pParam); . . . private: int m_nThreadId; } thread.cpp void StartThread(void* pParam) { do some initialization here.... . . . } bool CThread::ThreadCreate() { SStartup vStartup; // contains a pointer to this thread and other useful stuff m_nThreadId = ::_beginthread( CThread::StartThread ,NULL ,32768 ,(void*)vStartup ); if (m_nThreadId == -1) { Some sort of error reporting here... return false; } ::DosSleep(100); // let thread initialize return true; } Call to StartThread then posts a ::DosWaitThread(...) waiting for this second thread to complete and just hangs forever.... Breakpoint on the if (m_nThreadId == -1) line indicates m_nThreadId is a valid threadid. IPMD (debugger) reports that there are two threads running. But StartThread never gets called!!! It is as if _beginthread cannot find the address??? I have tried this using an extern "C" initialization proc instead of a static member proc with has the exact same results. A new thread but init function called. Anyone with any idea??? Threads via classes appear to be completely brokein with Innotek GCC at this time.... Must be missing something basic but cannot figure it out. **= Email 3 ==========================** Date: Wed, 02 Jun 2004 23:11:48 -0800 From: "Dave Yeo" Subject: Re: Os/2 Thread classes On Wed, 2 Jun 2004 10:44:14 -0500, Dave Webster wrote: >Anyone with any idea??? Threads via classes appear to be >completely brokein with Innotek GCC at this time.... Must be missing >something basic but cannot figure it out. You might want to look at Mozilla's threading code, seems to be C++ but I can't find where its encapsalated as a class but it must be as Mozilla supports threading on quite a few architectures. I don't know enough to really tell exactly whats happening and Mozilla is big. Anyways in mozilla\nsprpub\pr\src\md\os2\os2thred.c theres some interesting code and comments. Dave **= Email 4 ==========================** Date: Thu, 03 Jun 2004 10:28:56 +0200 (CEST) From: Stefan.Neis at t-online.de Subject: Re: Os/2 Thread classes Dave Webster schrieb: > And for wxWidgets--- > > And this is confusing to me. The wxThreadModule (I have > something very > similar in my class as well) has the static global > CritsecGui which gets > entered OnInit and does not get exitted until OnExit. > This should cause the > same problem in wxOS2's threads but it doesn't???? > Entering a critical > section stops processing in all other threads until > exitting, but the wxOS2 > threads do not block when this Critsec is entered??? Probably a problem with naming conventions... Note that a critical section on OS/2 and a critical section on Windows are completely different things. wxCriticalSection on OS/2 is implemented by _not_ using OS/2's critical sections (instead it's using wxMutex which is using OS/2's mutex semaphores), trying to achieve the behaviour seen on Windows and expected by wxWindows thread class. HTH, Stefan **= Email 1 ==========================** Date: Thu, 03 Jun 2004 10:28:56 +0200 (CEST) From: Stefan.Neis at t-online.de Subject: Re: Os/2 Thread classes Dave Webster schrieb: > And for wxWidgets--- > > And this is confusing to me. The wxThreadModule (I have > something very > similar in my class as well) has the static global > CritsecGui which gets > entered OnInit and does not get exitted until OnExit. > This should cause the > same problem in wxOS2's threads but it doesn't???? > Entering a critical > section stops processing in all other threads until > exitting, but the wxOS2 > threads do not block when this Critsec is entered??? Probably a problem with naming conventions... Note that a critical section on OS/2 and a critical section on Windows are completely different things. wxCriticalSection on OS/2 is implemented by _not_ using OS/2's critical sections (instead it's using wxMutex which is using OS/2's mutex semaphores), trying to achieve the behaviour seen on Windows and expected by wxWindows thread class. HTH, Stefan