Sophie

Sophie

distrib > Fedora > 18 > i386 > by-pkgid > 55494225df0b8698de1a4d424d8d98b3 > files > 79

UpTools-devel-8.6.3-2.fc18.i686.rpm

/* UpTools v8.6
 *
 * Copyright (c) 2005-2013 Fundacion Universidad de Palermo (Argentina).
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * 4. Redistributions of any form whatsoever must retain the following
 *    acknowledgment: 'This product includes software developed by the
 *    "Universidad de Palermo, Argentina" (http://www.palermo.edu/).'
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include <UpTools/UpThreadSpecific.h>
#include <iostream>
using namespace std;

// this program is to test the speed and correctness of the
// UpThreadSpecificPtr template
// I also compares it to the perfromance obtained by a manual replacement
// for pthread_getspecific and get_setspecific

class AuxThreadPtr {
	public:
		AuxThreadPtr*		next;
		const pthread_t	self;
		void* 				ptr;
	public:
		AuxThreadPtr(pthread_t _self)
			: next(0), self(_self), ptr(0) { }
		~AuxThreadPtr()
			{  }
};

AuxThreadPtr* firstPtr=0;
UpMutex mx;


void*& getPtr() {
	void** pptr;
	pthread_t self = pthread_self();
	mx.lock();
	if( firstPtr==0 ) {
		firstPtr = new AuxThreadPtr(self);
		pptr = &(firstPtr->ptr);
	} else {
		AuxThreadPtr* atptr;
		for( atptr=firstPtr; atptr->self!=self; atptr=atptr->next )
			if( atptr->next==0 ) {
				atptr = atptr->next = new AuxThreadPtr(self);
				break;
			}
			pptr = &(atptr->ptr);
	}
	mx.unlock();
	return *pptr;
}	



/////////////////////////////////////////////////////////////////////////////



UpThreadSpecificPtr<unsigned int> specificPtr;
unsigned int whileCount=10;

void processSpecificData1() {
	++(*specificPtr);
}
void processSpecificData2() {
	++(*(unsigned int*)getPtr());
}

class Thread1 : public UpThread {
public:
	unsigned int n;
	unsigned int count;
	UpTimeVal t;
	Thread1(unsigned int repeat)
		: n(0), count(repeat) {}
	void* run() {
		specificPtr = &n;
		t.tic();
		while(count--)
			processSpecificData1();
		t.toc();
		return 0;
	}
};

class Thread2 : public UpThread {
public:
	unsigned int n;
	unsigned int count;
	UpTimeVal t;
	Thread2(unsigned int repeat)
		: n(0), count(repeat) {}
	void* run() {
		unsigned int*& p = (unsigned int*&)getPtr();
		p = &n;
		t.tic();
		while(count--)
			processSpecificData2();
		t.toc();
		return 0;
	}
};


int main(int argc,char* argv[]) {
	int repeat = (argc>1) ? atoi(argv[1]) : 100000;
	cout<<"test using UpThreadSpecificPtr"<<endl;
	Thread1 a(repeat),b(repeat),c(repeat),d(repeat),e(repeat),f(repeat),g(repeat),h(repeat);
	a.create();
	b.create();
	c.create();
	d.create();
	e.create();
	f.create();
	g.create();
	h.create();
	a.join(); cout<<"joined thread lasted "<<a.t<<" and counted "<<a.n<<endl;
	b.join(); cout<<"joined thread lasted "<<b.t<<" and counted "<<b.n<<endl;
	c.join(); cout<<"joined thread lasted "<<c.t<<" and counted "<<c.n<<endl;
	d.join(); cout<<"joined thread lasted "<<d.t<<" and counted "<<d.n<<endl;
	e.join(); cout<<"joined thread lasted "<<e.t<<" and counted "<<e.n<<endl;
	f.join(); cout<<"joined thread lasted "<<f.t<<" and counted "<<f.n<<endl;
	g.join(); cout<<"joined thread lasted "<<g.t<<" and counted "<<g.n<<endl;
	h.join(); cout<<"joined thread lasted "<<h.t<<" and counted "<<h.n<<endl;
	cout<<"test using pthread_self() and mx.lock()"<<endl;
	Thread1 A(repeat),B(repeat),C(repeat),D(repeat),E(repeat),F(repeat),G(repeat),H(repeat);
	A.create();
	B.create();
	C.create();
	D.create();
	E.create();
	F.create();
	G.create();
	H.create();
	A.join(); cout<<"joined thread lasted "<<A.t<<" and counted "<<A.n<<endl;
	B.join(); cout<<"joined thread lasted "<<B.t<<" and counted "<<B.n<<endl;
	C.join(); cout<<"joined thread lasted "<<C.t<<" and counted "<<C.n<<endl;
	D.join(); cout<<"joined thread lasted "<<D.t<<" and counted "<<D.n<<endl;
	E.join(); cout<<"joined thread lasted "<<E.t<<" and counted "<<E.n<<endl;
	F.join(); cout<<"joined thread lasted "<<F.t<<" and counted "<<F.n<<endl;
	G.join(); cout<<"joined thread lasted "<<G.t<<" and counted "<<G.n<<endl;
	H.join(); cout<<"joined thread lasted "<<H.t<<" and counted "<<H.n<<endl;
	return 0;
}