|
barrier_increment.cc
// // $Id: barrier_increment.cc,v 1.5 2003/10/30 15:05:12 cholm Exp $ // // Test of threads - C %example ex14.c // Copyright (C) 2002 Christian Holm Christensen <cholm@nbi.dk> // // 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 // #ifndef OPTION_HH #include "option.hh" #endif #ifndef THREADMM_thread #include <threadmm/thread.hh> #endif #ifndef THREADMM_barrier #include <threadmm/barrier.hh> #endif #ifndef THREADMM_mutex #include <threadmm/mutex.hh> #endif #ifndef __VECTOR__ #include <vector> #endif #ifndef __FUNCTIONAL__ #include <functional> #endif #ifndef __ALGORITHM__ #include <algorithm> #endif #ifndef __TYPEINFO__ #include <typeinfo> #endif using namespace std; template <typename T> struct reset : public unary_function<T, void> { void operator()(T& x) { x = 0; } }; template <typename T> struct print : public unary_function<T, void> { void operator()(T x) { cout << setw(2) << x << " "; } }; namespace example { class meeting : public threadmm::thread { public: static threadmm::barrier** _barrier; static threadmm::mutex _lock; static int _iterations; static int _num; static vector<int> _counters; static vector<int> _serial; int _id; public: meeting(int id) : _id(id) {} void* operator()() { int ret = 0; for (int i = 0; i < _iterations; i++) { if (_id == 0) { for_each(_counters.begin(), _counters.end(), reset<int>()); for_each(_serial.begin(), _serial.end(), reset<int>()); } // Wait at the last barrier. _barrier[_num - 1]->wait(); for (int j = _id; j < _num; j++) { _lock.lock(); _counters[j]++; _lock.unlock(); // wait at this barrier - wait for the rest. bool flag = _barrier[j]->wait(); if (_id == 0 && _counters[j] != j + 1) { cerr << "Barriers in round " << j << " released, but count is " << _counters[j] << endl; ret = 1; } if (flag) { _lock.lock(); _serial[j]++; _lock.unlock(); } // and wait again. _barrier[j]->wait(); if (_id == 0) { cout << "After try " << j << " in iteration " << i << endl << " Counters: " << flush; for_each(_counters.begin(), _counters.end(), print<int>()); cout << endl << " Serials: " << flush; for_each(_serial.begin(), _serial.end(), print<int>()); cout << endl; if (_serial[j] != 1) { cerr << "Not exactly one serial thread in round " << j << endl; ret = 1; } } } // _num } // _iterations return reinterpret_cast<void*>(ret); } }; threadmm::barrier** meeting::_barrier = 0; threadmm::mutex meeting::_lock; int meeting::_iterations = 0; int meeting::_num = 0; vector<int> meeting::_counters; vector<int> meeting::_serial; class barrier_increment { public: barrier_increment() {} int run() { ios::sync_with_stdio(true); cout.setf(ios::unitbuf); cerr.setf(ios::unitbuf); meeting::_iterations = 5; meeting::_num = 5; meeting::_counters.resize(meeting::_num); meeting::_serial.resize(meeting::_num); try { meeting::_barrier = new threadmm::barrier * [meeting::_num]; for (int i = 0; i < meeting::_num; i++) meeting::_barrier[i] = new threadmm::barrier(i+1); meeting** threads = new meeting * [meeting::_num]; for (int i = 0; i < meeting::_num; i++) { threads[i] = new meeting(i); threads[i]->run(); } for (int i = 0; i < meeting::_num; i++) threads[i]->join(); } catch(exception& e) { cerr << e.what() << endl; return 1; } cout << "Ok" << endl; return 0; } }; } //_______________________________________________________________________ int main(int argc, char** argv) { if (!example::options(argc, argv)) return 0; example::barrier_increment exa; return exa.run(); } //_______________________________________________________________________ // // EOF // Last update Tue Nov 9 12:40:50 2004 Christian Holm Created by DoxyGen 1.3.9.1 |