[Tdg] overloading new puzzle
Graham Wakefield
lists at grahamwakefield.net
Sun Aug 5 13:16:02 PDT 2007
Here's some code (I'm putting it in the repo branches) to test
pthread_self. I'm running 1024 threads with 1024 iterations calling
printf() and testing against pthread_self on each one (thats a
million tests and it is definitely spreading across both my cores
when I look at the CPU monitor).
I've run it a few times and it never fails.
It's slow because of the printfs, but if I comment out the DOPRINT
macro I run 10^9 tests and no fails, and it's fast enough I think.
I think pthread_self() is a viable solution - but someone should say
if there's something amiss with my test.
Also I didn't try changing the pthread_attr_t values - maybe this
will have an impact?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUMTHREADS (1024)
#define DOPRINT
#ifdef DOPRINT
#define NUMITERATIONS (1024)
#else
#define NUMITERATIONS (1024 * 1024)
#endif
// thread function userdata
struct TestData
{
pthread_t thread; // used to test identity with pthread_self()
int id; // for printf
};
// array of pthreads
TestData tests[NUMTHREADS];
// global result flag
bool failed = false;
// thread callback:
void * testfunc(void * arg)
{
TestData * test = (TestData *)arg;
for (int i=0;i<NUMITERATIONS;i++)
{
// thread identity test
if (test->thread != pthread_self()) {
printf("ERROR! pthread arg %p is not pthread_self() %p\n",
test->thread, pthread_self());
failed = true;
//exit(-1);
}
// pretty print to show thread interleaving and occaisional status
#ifdef DOPRINT
if (i % 16) {
printf(",", i);
} else {
printf("%i[%i]: %p == %p\n",
test->id, i, test->thread, pthread_self());
}
#endif
}
}
int main (int argc, char * const argv[])
{
pthread_attr_t attr;
pthread_attr_init(&attr);
int err;
// spawn some threads
for (int i=0;i<NUMTHREADS;i++)
{
tests[i].id = i;
err = pthread_create(&tests[i].thread, // pthread_t
&attr, // pthread_attr_t
testfunc, // startroutine
&tests[i] // void * arg
);
#ifdef DOPRINT
printf("pthread created %i: %p from thread %p\n", i, tests
[i].thread, pthread_self());
#endif
if (err) {
printf("spawn %i err %i\n", i, err); // too many threads?
exit(-1);
}
}
pthread_attr_destroy(&attr);
// wait for all the threads to finish:
for (int i=0;i<NUMTHREADS;i++) pthread_join(tests[i].thread, NULL);
//print result:
printf("\ntest complete: %i threads of %i iterations\nfailed?: %i\n",
NUMTHREADS, NUMITERATIONS, failed);
return 0;
}
On Aug 5, 2007, at 10:00 AM, Alex Norman wrote:
> pthread_self()
> "The pthread_self() function returns the thread ID of the calling
> thread."
>
> I assume having multiple threads going isn't a problem because it
> returns the
> id of the calling thread, not the "current thread"
>
> -Alex
>
> On 0, Wesley Smith <wesley.hoke at gmail.com> wrote:
>> The problem with getCurrentThread() is that there could be multiple
>> current threads on multiprocessor machines so I don't think this is
>> viable.
>>
>> wes
>>
>> On 8/4/07, Wesley Smith <wesley.hoke at gmail.com> wrote:
>>> So I have a functioning system right now. Here's how it works:
>>>
>>> For each event class, I'm creating a static instance of the class.
>>> For creating new events, there's an EventFactory that has an
>>> internal
>>> memory pool. It does a sizeof() on the event type to be created and
>>> allocates that much memory from the pool. It then hands off the
>>> uninitialized memory to the event class' static void create(Event
>>> *e);
>>> method. This does a memcpy (and yes it works) to initialize the
>>> memory.
>>>
>>> This event is then sent off to a central hub where it is distributed
>>> to the appropriate queue. when the queue is done with the event it
>>> class Event::recycle() which sends it back to the factory for
>>> recycling the memory back into its memory pool.
>>>
>>> This is all threadsafe to boot. I'm about to test is with
>>> sending OSC
>>> messages from one thread to a graphics thread and see how things pan
>>> out, but my test code (which is single threaded right now) shows
>>> things to be working well.
>>>
>>> There are some design issues about API we need to discuss like what
>>> defines a mint::Object or a mint::Event. Are they threadsafe?
>>> Have a
>>> memory pool? I think there is a very strong need for an
>>> EventFactory
>>> so how tightly is EventFactory coupled with Event? How is reference
>>> counting of Events done? How can one event be sent to multiple
>>> places? Is this even necessary?
>>>
>>> Once I get the networking test done, I'll try and summarize the
>>> design
>>> and potential issues for discussion in a more formal manner and put
>>> this stuff in SVN.
>>>
>>> wes
>>>
>> _______________________________________________
>> Tdg mailing list
>> Tdg at mat.ucsb.edu
>> http://zydeco.mat.ucsb.edu/mailman/listinfo/tdg
> _______________________________________________
> Tdg mailing list
> Tdg at mat.ucsb.edu
> http://zydeco.mat.ucsb.edu/mailman/listinfo/tdg
grrr waaa
www.grahamwakefield.net
More information about the Tdg
mailing list