Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

Semaphores.cc

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 /* ******************************************************* 00037 * $Id: Semaphores.cc,v 1.3 2004/07/21 16:30:54 chrish42 Exp $ 00038 * This file is part of the PLearn library. 00039 ******************************************************* */ 00040 00041 #include <cstring> 00042 #include <cerrno> 00043 #include <plearn/base/general.h> 00044 #include "Semaphores.h" 00045 00046 namespace PLearn { 00047 using namespace std; 00048 00049 ResourceSemaphore::ResourceSemaphore(int nb_semaphores) 00050 : owner(true), n_semaphores(nb_semaphores) 00051 { 00052 // allocate a semaphore 00053 int rv=semget(IPC_PRIVATE, n_semaphores, 0666 | IPC_CREAT); 00054 if (rv == -1) 00055 PLERROR("ResourceSemaphore::ResourceSemaphore(%d) semget returns -1, %s", 00056 nb_semaphores,strerror(errno)); 00057 else id.id=rv; 00058 cout << "allocated semaphore " << id.id << endl; 00059 clearAnyLock(); // sets all the semaphore values to 1 00060 } 00061 00062 ResourceSemaphore::ResourceSemaphore(SemId semid) : id(semid), owner(false) 00063 { 00064 struct semid_ds buf; 00065 semun u; 00066 u.buf = &buf; 00067 int r=semctl(id.id,0,IPC_STAT,u); 00068 if (r == -1) 00069 PLERROR("ResourceSemaphore:: slave ResourceSemaphore(%d) semctl returns -1, %s", 00070 id.id,strerror(errno)); 00071 n_semaphores = u.buf->sem_nsems; 00072 } 00073 00074 void ResourceSemaphore::lock(int resource) 00075 { 00076 struct sembuf op; 00077 op.sem_num = resource; 00078 op.sem_op = -1; // wait for value = 1 and then decrement to zero 00079 op.sem_flg = 0; 00080 int rv=semop(id.id,&op,1); 00081 if (rv == -1) 00082 PLERROR("ResourceSemaphore::lock(%d) semop failed, %s", 00083 resource,strerror(errno)); 00084 } 00085 00086 void ResourceSemaphore::unlock(int resource) 00087 { 00088 if (!locked(resource)) 00089 PLERROR("ResourceSemaphore::unlock(%d), trying to unlock an unlocked resource", 00090 resource); 00091 struct sembuf op; 00092 op.sem_num = resource; 00093 op.sem_op = 1; // increment value back to 1 00094 op.sem_flg = 0; 00095 int rv=semop(id.id,&op,1); 00096 if (rv == -1) 00097 PLERROR("ResourceSemaphore::unlock(%d) semop failed, %s", 00098 resource,strerror(errno)); 00099 } 00100 00101 bool ResourceSemaphore::locked(int resource) 00102 { 00103 semun v; v.val=0; 00104 int value=semctl(id.id,resource,GETVAL,v); 00105 return (value==0); 00106 } 00107 00108 void ResourceSemaphore::clearAnyLock() 00109 { 00110 for (int i=0;i<n_semaphores;i++) 00111 clearAnyLock(i); 00112 } 00113 00114 void ResourceSemaphore::clearAnyLock(int resource) 00115 { 00116 // set the semaphore values to 1 (meaning they are in "unlocked" state") 00117 semun v; v.val=1; 00118 int rv=semctl(id.id,resource,SETVAL,v); 00119 if (rv == -1) 00120 PLERROR("ResourceSemaphore::clearAnyLock(%d) semctl returns -1, %s", 00121 resource,strerror(errno)); 00122 } 00123 00124 ResourceSemaphore::~ResourceSemaphore() 00125 { 00126 if (owner) 00127 { 00128 semun v; v.val=0; 00129 int rv=semctl(id.id,0,IPC_RMID,v); 00130 if (rv == -1) 00131 PLERROR("ResourceSemaphore::~ResourceSemaphore semctl failed, %s", 00132 strerror(errno)); 00133 cout << "released semaphore " << id.id << endl; 00134 } 00135 } 00136 00137 CountEventsSemaphore::CountEventsSemaphore(int nb_semaphores) 00138 : owner(true), n_semaphores(nb_semaphores) 00139 { 00140 // allocate a semaphore 00141 int rv=semget(IPC_PRIVATE, n_semaphores, 0666 | IPC_CREAT); 00142 if (rv == -1) 00143 PLERROR("CountEventsSemaphore::CountEventsSemaphore(%d) semget returns -1, %s", 00144 nb_semaphores,strerror(errno)); 00145 else id.id=rv; 00146 00147 cout << "allocated semaphore " << id.id << endl; 00148 00149 // set the semaphore values to 0 (meaning that initially the counters are at 0) 00150 semun v; v.val=0; 00151 for (int i=0;i<n_semaphores;i++) 00152 { 00153 rv=semctl(id.id,i,SETVAL,v); 00154 if (rv == -1) 00155 PLERROR("CountEventsSemaphore::CountEventsSemaphore(%d) semctl returns -1, %s", 00156 nb_semaphores,strerror(errno)); 00157 } 00158 } 00159 00160 CountEventsSemaphore::CountEventsSemaphore(SemId semid) 00161 : id(semid), owner(false) 00162 { 00163 struct semid_ds buf; 00164 semun u; 00165 u.buf = &buf; 00166 int r=semctl(id.id,0,IPC_STAT,u); 00167 if (r == -1) 00168 PLERROR("CountEventsSemaphore:: slave CountEventsSemaphore(%d) semctl returns -1, %s", 00169 id.id,strerror(errno)); 00170 n_semaphores = u.buf->sem_nsems; 00171 } 00172 00173 void CountEventsSemaphore::signal(int type) 00174 { 00175 struct sembuf op; 00176 op.sem_num = type; 00177 op.sem_op = 1; // increment value 00178 op.sem_flg = 0; 00179 int rv=semop(id.id,&op,1); 00180 if (rv == -1) 00181 PLERROR("CountEventsSemaphore::signal(%d) semop failed, %s", 00182 type,strerror(errno)); 00183 } 00184 00185 int CountEventsSemaphore::value(int type) 00186 { 00187 semun v; v.val=0; 00188 return semctl(id.id,type,GETVAL,v); 00189 } 00190 00191 void CountEventsSemaphore::wait(int n_occurences, int type) 00192 { 00193 struct sembuf op; 00194 op.sem_num = type; 00195 op.sem_op = -n_occurences; // wait until n_occurences is reached 00196 op.sem_flg = 0; 00197 int rv=0; 00198 do // this loop is to deal with possible interrupts which 00199 rv=semop(id.id,&op,1); // will force return of semop before 00200 while (rv==-1 && errno==EINTR); // the count is reached 00201 if (rv == -1) 00202 PLERROR("CountEventsSemaphore::wait(%d,%d) semop failed, %s", 00203 n_occurences,type,strerror(errno)); 00204 } 00205 00206 void CountEventsSemaphore::setValue(int value,int resource) 00207 { 00208 semun v; v.val=value; 00209 int rv=semctl(id.id,resource,SETVAL,v); 00210 if (rv == -1) 00211 PLERROR("ResourceSemaphore::setValue(%d,%d) semctl returns -1, %s", 00212 value,resource,strerror(errno)); 00213 } 00214 00215 CountEventsSemaphore::~CountEventsSemaphore() 00216 { 00217 if (owner) 00218 { 00219 semun v; v.val=0; 00220 int rv=semctl(id.id,0,IPC_RMID,v); 00221 if (rv == -1) 00222 PLERROR("CountEventsSemaphore::~CountEventsSemaphore semctl failed, %s", 00223 strerror(errno)); 00224 cout << "released semaphore " << id.id << endl; 00225 } 00226 } 00227 00228 } // end of namespace PLearn

Generated on Tue Aug 17 16:05:06 2004 for PLearn by doxygen 1.3.7