// ------------------------------- // // -------- Start of File -------- // // ------------------------------- // // ----------------------------------------------------------- // // C++ Source Code File Name: testprog.cpp // Compiler Used: MSVC, BCC32, GCC, HPUX aCC, SOLARIS CC // Produced By: DataReel Software Development Team // File Creation Date: 03/25/2000 // Date Last Modified: 06/17/2016 // Copyright (c) 2001-2024 DataReel Software Development // ----------------------------------------------------------- // // ------------- Program Description and Details ------------- // // ----------------------------------------------------------- // /* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Test program used to the basic functionality of the Thread Pool class. */ // ----------------------------------------------------------- // #include "gxdlcode.h" #if defined (__USE_ANSI_CPP__) // Use the ANSI Standard C++ library #include <iostream> using namespace std; // Use unqualified names for Standard C++ library #else // Use the old iostream library by default #include <iostream.h> #endif // __USE_ANSI_CPP__ #include "thrpool.h" #include "gthreadt.h" #ifdef __MSVC_DEBUG__ #include "leaktest.h" #endif void PausePrg() // Pause the program and wait for the user to press enter. { // Pause the program until enter is pressed cout << "\n" << flush; cout << "Press Enter to continue..." << "\n" << flush; cin.get(); } void ScrollForward(thrPool &pool) { cout << "Walking through the pool..." << "\n" << flush; thrPoolNode *ptr = pool.GetHead(); while(ptr) { cout << (char)ptr->GetThreadPtr()->GetObjectID() << ' '; ptr = ptr->GetNext(); } cout << "\n" << flush; } void RewindPool(thrPool &pool) { cout << "Walking through the pool in a backward direction..." << "\n" << flush; thrPoolNode *ptr = pool.GetTail(); // Walk through the pool in a backward direction while(ptr) { cout << (char)ptr->GetThreadPtr()->GetObjectID() << ' '; ptr = ptr->GetPrev(); } cout << "\n" << flush; } int main() { #ifdef __MSVC_DEBUG__ InitLeakTest(); #endif thrPool pool; thrPoolNode *ptr; cout << "Loading data elements into the pool..." << "\n" << flush; thrPoolNode *na = new thrPoolNode; thrPoolNode *nb = new thrPoolNode; thrPoolNode *nc = new thrPoolNode; thrPoolNode *nd = new thrPoolNode; thrPoolNode *n1 = new thrPoolNode; thrPoolNode *n2 = new thrPoolNode; thrPoolNode *n3 = new thrPoolNode; thrPoolNode *n4 = new thrPoolNode; // Allocating some memory buffers const unsigned num_blocks = 9; gxThread_t *buf[num_blocks]; unsigned i; for(i = 0; i < num_blocks; i++) { buf[i] = new gxThread_t; // Set an arbitary object ID stating starting with ASCII character 'A' buf[i]->SetObjectID(65+i); } na->SetThreadPtr(buf[0]); nb->SetThreadPtr(buf[1]); nc->SetThreadPtr(buf[2]); nd->SetThreadPtr(buf[3]); // Load some pool elements pool.InsertAfter(pool.GetHead(), na); pool.InsertAfter(na, nb); pool.InsertAfter(nb, nc); pool.InsertAfter(nc, nd); n1->SetThreadPtr(buf[4]); n2->SetThreadPtr(buf[5]); n3->SetThreadPtr(buf[6]); n4->SetThreadPtr(buf[7]); // Testing insert functions pool.InsertBefore(na, n1); pool.InsertBefore(nc, n2); pool.InsertAfter(nb, n3); pool.InsertAfter(nd, n4); // Reordering the pool pool.MoveToBack(na); pool.MoveAfter(na, nc); pool.MoveBefore(nc, nb); pool.MoveAfter(nc, nd); pool.MoveAfter(nd, n2); pool.MoveBefore(n2, n1); pool.MoveAfter(n2, n3); pool.MoveAfter(n3, n4); ScrollForward(pool); RewindPool(pool); PausePrg(); cout << "Adding another item to the pool..." << "\n" << flush; ptr = pool.AddThread(buf[8]); ScrollForward(pool); PausePrg(); cout << "Moving pool item to the front of the pool" << "\n" << flush; pool.MoveToFront(ptr); ScrollForward(pool); cout << "Moving item to the back of the pool..." << "\n" << flush; pool.MoveToBack(ptr); ScrollForward(pool); PausePrg(); cout << "Removing the head of the pool..." << "\n" << flush; ptr = pool.GetHead(); gxThread_t *tptr = pool.RemoveNode(ptr); if(tptr) delete tptr; // Prevent memory leaks ScrollForward(pool); cout << "Removing the tail of the pool..." << "\n" << flush; ptr = pool.GetTail(); tptr = pool.RemoveNode(ptr); if(tptr) delete tptr; // Prevent memory leaks ScrollForward(pool); PausePrg(); cout << "Testing for memory leaks..." << "\n" << flush; unsigned len = sizeof(gxThread_t); const unsigned num_to_allocate = 1000; // 1000 * 1000; const unsigned mem_bufs = (sizeof(thrPoolNode) + len) * num_to_allocate; cout << "Allocating " << mem_bufs << " bytes..." << "\n" << flush; // Clear the thread pool without checking the status of each thread pool.ClearPool(); unsigned count1 = 0; unsigned count2 = 0; for(i = 0; i < num_to_allocate; ++i) { gxThread_t *sbuf = new gxThread_t; count1 += sizeof(sbuf); if(!sbuf) { cout << "Memory allocation error at " << (count1+count2) << " bytes" << "\n" << flush; break; } count2 += sizeof(thrPoolNode); if(!pool.AddThread(sbuf)) { cout << "Memory allocation error at " << (count1+count2) << " bytes" << "\n" << flush; break; } } cout << "Done" << "\n" << flush; PausePrg(); cout << "Releasing memory allocated back to the heap..." << "\n" << flush; while(!pool.IsEmpty()) { // Clear the pool, giving the application a chance to check the // status of each thread. gxThread_t *t = pool.RemoveTail(); if(t) { // Process the thread and release any memory the thread is holding // ... delete t; } } pool.MakeEmpty(); // The thread pool is no empty PausePrg(); cout << "Exiting..." << "\n" << flush; cout << "\n" << flush; return 0; } // ----------------------------------------------------------- // // ------------------------------- // // --------- End of File --------- // // ------------------------------- //