Is threads CodeWarrior project broken?
Hi, I'm trying to build the threads library on Codewarrior with the .mcp project supplied in libs/thread/build/ (using CW9, OS X 10.2.8), but Codewarrior says the file is not a project file. Is it broken? I could probably recreate it, but I'm not sure about about what source files to include for the Mac - there's all the extra stuff under src/mac/ and then what about the src/mac/msl_replacements/ stuff? Any help gratefully received. I'd like to do a multi-target project for Mac and Win32; tips for source files for Win32 would be helpful too. Thanks. Steve.
At 7:30 PM +0000 10/31/03, Steve Folly wrote:
Hi,
I'm trying to build the threads library on Codewarrior with the .mcp project supplied in libs/thread/build/ (using CW9, OS X 10.2.8), but Codewarrior says the file is not a project file.
Is it broken?
In CW9, Metrowerks has supplied a threads library that has the exact same interface as boost::threads as part of their standard library. -- -- Marshall Marshall Clow Idio Software mailto:marshall@idio.com Hey! Who messed with my anti-paranoia shot?
On 1/11/03 4:12 pm, in article p0610030ebbc98bb11a69@[192.168.16.235],
"Marshall Clow"
At 7:30 PM +0000 10/31/03, Steve Folly wrote:
Hi,
I'm trying to build the threads library on Codewarrior with the .mcp project supplied in libs/thread/build/ (using CW9, OS X 10.2.8), but Codewarrior says the file is not a project file.
Is it broken?
In CW9, Metrowerks has supplied a threads library that has the exact same interface as boost::threads as part of their standard library.
Thanks for that. Unfortunately, we try not to rely on CW specific libraries because of requirements we have to be able to port to other compilers. It would be nice if the threads CW project could be fixed. Thanks. Steve.
It would be nice if the threads CW project could be fixed.
Yes - the project file is corrupted. I think something must have happened to it when it was checked into CVS - either it was interpreted as text instead of binary, or something funky like that happened. It is pretty easy to recreate your own though - that is what I did and I am using the boost threads successfully. All you have to do is include all of the sources in the /libs/thread/src folder and in the /libs/thread/src/mac folder. It works just fine. With the recent versions of Boost, however, some stuff broke in the thread classes. It's pretty easy to fix, I fixed it locally on my machine. I need to submit the changes back to get them into the CVS repository, I am just lazy. :-) (Just kidding - I've been busy.) Here's a description of the problem from my initial e-mail about it (edited slightly for clarity):
I am having trouble getting the MP implementation of threads to compile. It seems to be having trouble with function pointers where the syntax function<type> is used.
I remember at one point it was mentioned that:
function
was deprecated and we were to use either the more universally supported:
functionN
or the cleaner:
function
instead if our compiler supported it.
(Mine doesn't support that last one yet.)
I am guessing that the oldest syntax was removed and no one has bothered to update the Mac carbon thread implementaton to compile again since then?
That one seems pretty easy to fix - just update to a supported syntax.
^ I've done that, updated to the functionN
I believe I have found a crashing bug in the boost thread classes on MacOS X, in the MP threads implementation.
I looked at the source and I think I have figured out what is wrong and how to fix it.
The thread_cleanup function, which on the MP threads implementation is called each time a boost thread exits, assumes that the "cleanup key" has been initialized. If it hasn't been initialized (ie you aren't using any thread specific storage), it still calls MPGetTaskStorageValue with the uninitialized key index.
Here are the first few lines of thread_cleanup:
void thread_cleanup() { cleanup_handlers* handlers = reinterpret_cast
( MPGetTaskStorageValue(key)); if(handlers != NULL) { ... If you have not used any thread-specific storage, key is an uninitialized variable when this gets called. Not good.
It looks like for the most part, rather than puking, MPGetTaskStorageValue is returning NULL when given an uninitialized key value, at least on 10.2.x. (I am doing some testing on the upcoming 10.3 release of MacOS X and noted that thread_cleanup crashes 100% of the time on this platform - I suspect MPGetTaskStorageValue is no longer returning NULL.) Since "key" is an uninitialized variable, I would think this would have unpredictable results and would crash occasionally even on 10.2.x, whenever "key" happened to start off as a value that was already in use maybe.
It seems to me that we should simply make sure that the key is inited when calling thread_cleanup like so:
boost::call_once(&init_cleanup_key, once);
This makes sure that the key is inited, even if get_handlers is never called. (Adding that line of code to the beginning of thread_cleanup cleared up my crashing problems on 10.3 immediately.)
Is that proper use of the call_once mechanism?
Anyway, my first thought was to look at the implementations of threads on the other platforms, since they don't have this call_once call in their cleanup function before accessing the key either.
It looks to me like, at least in the Windows code, the cleanup function is registered for the thread only during the get_handlers function, after the key is inited. If get_handlers is never called, the cleanup function never gets registered.
In the Mac implementation, however, cleanup_thread is called directly by the thread proxy object at the end of thread execution, and it gets called even if get_handlers has never been called and the key has never been initialized.
Here is a patch for my proposed fix. (I am sure there are other ways of fixing this too.)
Comments, anyone?
*** tss.orig.cpp Mon Oct 20 13:19:44 2003 --- tss.cpp Mon Oct 20 13:19:30 2003 *************** *** 126,131 **** --- 126,133 ----
void thread_cleanup() { + boost::call_once(&init_cleanup_key, once); + cleanup_handlers* handlers = reinterpret_cast
( MPGetTaskStorageValue(key)); if(handlers != NULL)
-- Bobby --------------------------------------------------------------------- Bobby Thomale Senior Software Developer Inoveon Corporation http://www.inoveon.com/ ---------------------------------------------------------------------
On Nov 4, 2003, at 10:11 AM, Bobby Thomale wrote:
I am having trouble getting the MP implementation of threads to compile. It seems to be having trouble with function pointers where the syntax function<type> is used.
I remember at one point it was mentioned that:
function
was deprecated and we were to use either the more universally supported:
functionN
or the cleaner:
function
instead if our compiler supported it.
(Mine doesn't support that last one yet.)
I am guessing that the oldest syntax was removed and no one has bothered to update the Mac carbon thread implementaton to compile again since then?
That one seems pretty easy to fix - just update to a supported syntax.
^ I've done that, updated to the functionN
syntax and it fixed the problem. I need to submit back the changes but I haven't yet. (SORRY!!!) Just let the compiler lead you around by the nose if you'd like, it will show you all of the places where this needs to change, and the change is straightforward. :-)
CodeWarrior 9 now supports the function
CodeWarrior 9 now supports the function
syntax. You can test for version 9 with: #if __MWERKS__ >= 0x3200
Oh cool, it's about time. Gives me something to look forward to once I get CW Pro 9. :-) (I am using 8.3 still BTW.) -- Bobby --------------------------------------------------------------------- Bobby Thomale Senior Software Developer Inoveon Corporation http://www.inoveon.com/ ---------------------------------------------------------------------
Hi On which package of GCC on Win32 is Boost tested: MinGW or CygWin?? Nick
participants (5)
-
Bobby Thomale
-
Howard Hinnant
-
Marshall Clow
-
Mikołaj Dawidowski
-
Steve Folly