00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
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
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();
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;
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;
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
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
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
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;
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;
00196 op.sem_flg = 0;
00197
int rv=0;
00198
do
00199 rv=semop(
id.
id,&op,1);
00200
while (rv==-1 && errno==EINTR);
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 }