PLearn 0.1
Semaphores.h
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // PLearn (A C++ Machine Learning Library)
00004 // Copyright (C) 2000 Yoshua Bengio and University of Montreal
00005 //
00006 
00007 // Redistribution and use in source and binary forms, with or without
00008 // modification, are permitted provided that the following conditions are met:
00009 // 
00010 //  1. Redistributions of source code must retain the above copyright
00011 //     notice, this list of conditions and the following disclaimer.
00012 // 
00013 //  2. Redistributions in binary form must reproduce the above copyright
00014 //     notice, this list of conditions and the following disclaimer in the
00015 //     documentation and/or other materials provided with the distribution.
00016 // 
00017 //  3. The name of the authors may not be used to endorse or promote
00018 //     products derived from this software without specific prior written
00019 //     permission.
00020 // 
00021 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
00022 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00023 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
00024 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00025 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00026 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00027 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00028 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00029 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031 // 
00032 // This file is part of the PLearn library. For more information on the PLearn
00033 // library, go to the PLearn Web site at www.plearn.org
00034 
00035 /* *******************************************************      
00036  * $Id: Semaphores.h 8247 2007-11-12 20:22:12Z nouiz $
00037  * This file is part of the PLearn library.
00038  ******************************************************* */
00039 
00040 // Object-friendly interface to the POSIX semaphore utilities.
00041 // Here we have defined two types of semaphores: ResourceSemaphore
00042 // and CountEventsSemaphore. In both cases multiple semaphores
00043 // of the same type can be managed by the same object.
00044 //
00045 // A ResourceSemaphore allows to control exclusive access to
00046 // some resources (each controlled independently of the others),
00047 // using the lock/unlock methods. When a process tries to
00048 // take the lock while another has it, it will wait until
00049 // the controlling process releases the lock.
00050 //
00051 // A CountEventsSemaphore allows to count the number of occurences
00052 // of one or more events. Some processes can signal the occurence
00053 // of an event of a given type, without waiting. Other processes
00054 // may wait for the count for an event type to reach a certain
00055 // value (and then this value is reset to 0).
00056 //
00057 
00058 
00061 #ifndef SEMAPHORES_INC
00062 #define SEMAPHORES_INC
00063 
00064 #include <sys/sem.h>
00065 #include <sys/types.h>
00066 #include <sys/ipc.h>
00067 #include <sys/shm.h>
00068 
00069 namespace PLearn {
00070 using namespace std;
00071 
00072 
00073 #if (defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)) || defined(_NO_XOPEN4)
00074 
00075 #else
00076 
00077 union semun {
00078     int val;                    
00079     struct semid_ds *buf;       
00080     unsigned short int *array;  
00081     struct seminfo *__buf;      
00082 };
00083 #endif
00084 
00087 class SemId {
00088 public:
00089     int id;
00090     SemId(int i = -1) : id(i) {} 
00091     SemId(SemId& semid) : id(semid.id) {}
00092 };
00093 
00094 class ResourceSemaphore {
00095 protected:
00096     SemId id; 
00097     bool owner; 
00098 
00099     int n_semaphores; 
00100 
00101 public:
00102 
00104     ResourceSemaphore(int nb_semaphores=1);
00105 
00107     ResourceSemaphore(SemId semid);
00108 
00113     void lock(int resource=0);
00114 
00117     void unlock(int resource=0);
00118 
00120     bool locked(int resource=0);
00121 
00123     void clearAnyLock();
00125     void clearAnyLock(int resource);
00126 
00128     ~ResourceSemaphore();
00129 };
00130 
00131 class CountEventsSemaphore {
00132 protected:
00133     SemId id; 
00134     bool owner; 
00135 
00136     int n_semaphores; 
00137 
00138 public:
00139 
00141     CountEventsSemaphore(int nb_semaphores=1);
00142 
00144     CountEventsSemaphore(SemId semid);
00145 
00148     void signal(int type=0);
00149 
00154     void wait(int n_occurences, int type=0);
00155 
00157     int value(int type=0);
00158 
00160     void setValue(int value,int resource=0);
00161 
00163     ~CountEventsSemaphore();
00164 };
00165 
00166 template <class T>
00167 class SharedMemory {
00168 protected:
00169     SemId id; 
00170     bool owner; 
00171 
00172     int size_; 
00173     T* segment; 
00174 public:
00176     SharedMemory(int n_items=1) : owner(true) {
00177         size_ = n_items*sizeof(T);
00178         int rv=shmget(IPC_PRIVATE, size_, 0666 | IPC_CREAT);
00179         if (rv == -1) PLERROR("SharedMemory::SharedMemory, shmget failed:%s",strerror(errno));
00180         else id.id=rv;
00181         segment = (T*)shmat(id.id,0,0);
00182         if (segment == 0) 
00183             PLERROR("SharedMemory::SharedMemory, shmat failed trying to allocate %d bytes: err=%s",
00184                     size_,strerror(errno));
00185 
00186     }
00187 
00189     SharedMemory(SemId semid) : id(semid), owner(false) {
00190         struct shmid_ds buf;
00191         int r = shmctl(id.id,IPC_STAT,&buf);
00192         if (r == -1)
00193             PLERROR("SharedMemory:: slave SharedMemory(%d) shmctl returns -1, %s",
00194                     id.id,strerror(errno));
00195         size_ = buf.shm_segsz;
00196         segment = (T*)shmat(id.id,0,0);
00197     }
00198 
00200     T* data() const { return segment; }
00201 
00202     int size() const { return size_ / sizeof(T); }
00203 
00205     ~SharedMemory() {
00206         int rv=shmdt((char*)segment);
00207         if (rv == -1)
00208             PLERROR("SharedMemory::~SharedMemory (id=%d) shmdt failed, %s", 
00209                     id.id,strerror(errno));
00210         if (owner)
00211         {
00212             rv=shmctl(id.id,IPC_RMID,0);
00213             if (rv == -1)
00214                 PLERROR("SharedMemory::~SharedMemory (id=%d) shmctl failed, %s", 
00215                         id.id,strerror(errno));
00216             cout << "released shared memory segment ID = " << id.id << endl;
00217         }
00218     }
00219 };
00220 
00221 } // end of namespace PLearn
00222 
00223 #endif
00224 
00225 
00226 /*
00227   Local Variables:
00228   mode:c++
00229   c-basic-offset:4
00230   c-file-style:"stroustrup"
00231   c-file-offsets:((innamespace . 0)(inline-open . 0))
00232   indent-tabs-mode:nil
00233   fill-column:79
00234   End:
00235 */
00236 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines