Hi,
Is there a way to tell CodeWarrior to instantiate gloabal variables for each
thread ? (something like the __declspec(thread) in Visual) ?
Eric
Howard Hinnant - 07 Mar 2004 02:54 GMT
> Hi,
>
> Is there a way to tell CodeWarrior to instantiate gloabal variables for each
> thread ? (something like the __declspec(thread) in Visual) ?
If you're doing C++, Pro 9 introduces a nice thread-local-data smart
pointer:
#include <iostream>
#include <msl_thread>
Metrowerks::thread_specific_ptr<int> value;
void increment()
{
++*value;
}
Metrowerks::mutex cout_mutex;
void thread_proc()
{
value.reset(new int(0));
for (int i = 0; i < 1000; ++i)
increment();
Metrowerks::mutex::scoped_lock lock(cout_mutex);
std::cout << *value << '\n';
}
int main()
{
Metrowerks::thread_group threads;
for (int i = 0; i < 5; ++i)
threads.create_thread(&thread_proc);
thread_proc();
threads.join_all();
}
/*
1000
1000
1000
1000
1000
1000
*/
This example turns a "global" variable "value" into a thread local smart
pointer to an int, which each thread increments 1000 times and then
prints out. This is a very convenient format as you can create a
thread_specific_ptr to any type you want, and you can have as many of
these smart pointers as you want.
-Howard
Jim Schimpf - 07 Mar 2004 11:40 GMT
> > Hi,
> >
[quoted text clipped - 50 lines]
>
> -Howard
This is also part of the Pthreads standard so it's in Linux and UNIX also.
--jim
Eric VERGNAUD - 07 Mar 2004 11:51 GMT
dans l'article 5d6ed6b4.0403070340.58635a6d@posting.google.com, Jim Schimpf
à vze35xda@verizon.net a écrit le 7/03/04 12:40 :
> This is also part of the Pthreads standard so it's in Linux and UNIX also.
Can you provide a sample ?
Thanks,
Eric
> The default libraries are not. However, the libraries do have an
> option to be compiled as thread-safe. You need to recompile them with
[quoted text clipped - 4 lines]
> runtime library and the C++ library (if you use it), in addition to
> the C library!
Okay, thanks! Now, I wonder, does this apply to a Carbon app running
at interrupt level (Deferred Task) on OS9? Would it be safe to call
malloc() from interrupt on OS9, or does it ultimately call NewPtr()?
I guess, Carbon or not, I need to be running on OSX in order to
allocate memory in a pre-emptive context?
Frederick Cheung - 02 Mar 2004 09:46 GMT
> > The default libraries are not. However, the libraries do have an
> > option to be compiled as thread-safe. You need to recompile them with
[quoted text clipped - 10 lines]
> I guess, Carbon or not, I need to be running on OSX in order to
> allocate memory in a pre-emptive context?
The flag makes malloc call through to MPAllocateAligned.
You'd have to check whether that is safe at the deferred task, but i seem
to remember that it is. OTAllocMem is safe from deferred tasks though.
Fred
Thorrsten Froehlich - 02 Mar 2004 11:52 GMT
> > The default libraries are not. However, the libraries do have an
> > option to be compiled as thread-safe. You need to recompile them with
[quoted text clipped - 8 lines]
> at interrupt level (Deferred Task) on OS9? Would it be safe to call
> malloc() from interrupt on OS9, or does it ultimately call NewPtr()?
The define will enable use of the Multiprocessing Services API for
memory allocation and everything else that needs to be thread-safe.
The documentation of MP Services (version 2.0 and newer) details what
the API is useful for and what not. The API is fully supported in Mac
OS 9 without Carbon, but I do not recall if it can be used in a
deferred task or not.
> I guess, Carbon or not, I need to be running on OSX in order to
> allocate memory in a pre-emptive context?
Multiprocessing Services provides preemptive threading on Mac OS 9 and
earlier. You do not need CarbonLib to use it. However, you will need
to pay close attention to which other APIs you may use in a preemptive
thread. See the MP Services documentation for all the details - the
documentation used to be included in the MP Services SDK on the Apple
developer website as well as older ADC SDK CDs.
Thorsten
Tim - 03 Mar 2004 01:40 GMT
Thanks again for helpful info. Research indicates that it is not safe
to call MP services at interrupt level, which I assume would include
DeferredTask on OS9. OTAllocMem is safe at interrupt, by drawing from
special pools that are replenished by ordinary allocations at safe
times. Probably better to just do that myself, rather than learning
to use OT memory properly. Or, re-write my DeferredTask as an MP
Task.... not sure if there are any other advantages there.
Also, on my original concern regarding va_start() and vsprintf() at
interrupt time, I did find Apple sample code, debugf.c, for
interrupt-safe formatted printing. It uses va_start, but
re-implements vsprintf. So that must be where the interrupt problems
I ran into before came from.
Thorrsten Froehlich - 03 Mar 2004 09:54 GMT
> Thanks again for helpful info. Research indicates that it is not safe
> to call MP services at interrupt level, which I assume would include
[quoted text clipped - 3 lines]
> to use OT memory properly. Or, re-write my DeferredTask as an MP
> Task.... not sure if there are any other advantages there.
If Mac OS 8.x compatibility is not a major concern (also it is
available for those, fewer system functions can be called then), to
switch to MP Services is a good idea. Not to mention that they are
available under Carbon on Mac OS 9 and Mac OS X.
Plus, under Carbon many more (however, this is/was not documented
except for the Gestalt.h flag gestaltMPTrapCalls) functions can be
called from inside MP Services tasks as the Carbon library provides
the necessary logic to run them single-threaded. Even without, having
file-io in MP tasks (even without CarbonLib) is already good to handle
a lot of complex operations.
Thorsten