|
timed_rwlock.cc
// // $Id: timed_rwlock.cc,v 1.5 2003/10/30 15:05:12 cholm Exp $ // // Test of threads - C %example ex11.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_rwlock #include <threadmm/rwlock.hh> #endif #ifndef THREADMM_example_gettime #include "gettime.hh" #endif using namespace std; namespace example { threadmm::mutex io_lock; class rw : public threadmm::thread { public: enum { reader, writer }; private: int _id; int _kind; int _tries; struct timespec _delay; struct timespec _wait; public: static threadmm::rwlock* _lock; rw(bool read, int id) { _id = id; _kind = read ? reader : writer; _tries = read ? 3 : 4; } void* operator()() { _wait.tv_sec = 0; _wait.tv_nsec = 1000000L; _delay.tv_sec = 0; _delay.tv_nsec = 1000000L; try { for (int i = 0; i < _tries; i++) { do { gettime(_wait); _wait.tv_nsec += 2 * 1000000L; cout << "- " << (_kind == reader ? "reader" : "writer") << " thread " << _id << " tries again" << endl; } while (!(_kind == reader ? _lock->lock4read(&_wait) : _lock->lock4write(&_wait))); cout << "+ " << (_kind == reader ? "reader" : "writer") << " thread " << _id << " succeded" << endl; nanosleep(&_delay, NULL); if (!_lock->unlock()) cerr << "Failed to unlock" << std::endl; cout << "! " << (_kind == reader ? "reader" : "writer") << " thread " << _id << " released" << endl; } } catch (exception& e) { cerr << e.what() << endl; return 0; } return 0; } }; threadmm::rwlock* rw::_lock = 0; class timed_rwlock { private: public: int run() { // Sync I/O // ios::sync_with_stdio(true); // cout.setf(ios::unitbuf); // cerr.setf(ios::unitbuf); rw::_lock = new threadmm::rwlock(::threadmm::reader); try { const int n = 5; rw** writers = new rw*[n]; rw** readers = new rw*[n]; for (int i = 0; i < n; i++) { writers[i] = new rw(false, i); writers[i]->run(); } for (int i = 0; i < n; i++) { readers[i] = new rw(true, i); readers[i]->run(); } for (int i = 0; i < n; i++) writers[i]->join(); for (int i = 0; i < n; i++) readers[i]->join(); } catch (exception& e) { cout << e.what() << endl; return 1; } return 0; } }; } //_______________________________________________________________________ int main(int argc, char** argv) { if (!example::options(argc, argv)) return 0; example::timed_rwlock exa; return exa.run(); } //_______________________________________________________________________ // // EOF // Last update Tue Nov 9 12:40:50 2004 Christian Holm Created by DoxyGen 1.3.9.1 |