semaphore.cpp

Go to the documentation of this file.
00001 #ifndef SEMAPHORE_IMPLEMENTATION_FILE
00002 #define SEMAPHORE_IMPLEMENTATION_FILE
00003 
00004 /*****************************************************************************\
00005 *                                                                             *
00006 *  Name   : semaphore                                                         *
00007 *  Author : Chris Koeritz                                                     *
00008 *                                                                             *
00009 *******************************************************************************
00010 * Copyright (c) 1998-$now By Author.  This program is free software; you can  *
00011 * redistribute it and/or modify it under the terms of the GNU General Public  *
00012 * License as published by the Free Software Foundation; either version 2 of   *
00013 * the License or (at your option) any later version.  This is online at:      *
00014 *     http://www.fsf.org/copyleft/gpl.html                                    *
00015 * Please send any updates to: fred@gruntose.com                               *
00016 \*****************************************************************************/
00017 
00018 #include "mechanisms_implementation_only.h"
00019 #include "semaphore.h"
00020 
00021 #include <basis/function.h>
00022 #include <basis/istring.h>
00023 #include <basis/mutex.h>
00024 #include <basis/portable.h>
00025 
00026 //#define DEBUG_SEMAPHORE
00027   // uncomment if you want the debugging version.
00028 
00029 // the state of the threads using or trying to use the semaphore is reported
00030 // by "_current_state".  it is positive if there are still slots that are
00031 // available, zero if no slots are available, and negative if all the slots
00032 // are used _and_ processes are waiting for the semaphore.
00033 
00034 semaphore::semaphore(int concurrent_locks, int initial_locks_available)
00035 : _max_users(0),
00036   _locks_available(0),
00037   _wait_guard(new mutex),
00038   _signal_guard(new mutex),
00039   _current_state(0)
00040 {
00041   if (concurrent_locks < 1) concurrent_locks = 1;
00042   _max_users = concurrent_locks;
00043   if (initial_locks_available < 0) initial_locks_available = 0;
00044   else if (initial_locks_available > concurrent_locks)
00045     initial_locks_available = concurrent_locks;
00046   _locks_available = initial_locks_available;
00047   _current_state = _locks_available;
00048 }
00049 
00050 semaphore::~semaphore()
00051 {
00052   delete _wait_guard;
00053   _wait_guard = NIL;
00054   delete _signal_guard;
00055   _signal_guard = NIL;
00056 }
00057 
00058 void semaphore::establish_lock() { wait(); }
00059 
00060 void semaphore::repeal_lock() { signal(); }
00061 
00062 void semaphore::wait()
00063 {
00064   _wait_guard->lock();
00065   // if the semaphore's count is negative, we need to snooze.
00066   while (non_positive(_current_state)) portable::sleep_ms(10);
00067   // we're guaranteed that the state is now above zero; this function's the
00068   // only one that can decrement the state (other than by rollover).
00069   _current_state--;  // record that this thread got a lock.
00070   _wait_guard->unlock();
00071 }
00072 
00073 void semaphore::signal()
00074 {
00075   FUNCDEF("signal");
00076   _signal_guard->lock();
00077   _current_state++;  // release the lock that this thread had.
00078   if (_current_state > _max_users)
00079     LOG("semaphore::signal: logic error!  the semaphore is greater than "
00080         "its maximum!");
00081   _signal_guard->unlock();
00082 }
00083 
00084 
00085 #endif //SEMAPHORE_IMPLEMENTATION_FILE
00086 

Generated on Fri Nov 21 04:29:50 2008 for HOOPLE Libraries by  doxygen 1.5.1