[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