/* 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; }