1 //
2 // globcnt.cc
3 //
4 // Copyright (C) 1996 Limit Point Systems, Inc.
5 //
6 // Author: Curtis Janssen <cljanss@limitpt.com>
7 // Maintainer: LPS
8 //
9 // This file is part of the SC Toolkit.
10 //
11 // The SC Toolkit is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU Library General Public License as published by
13 // the Free Software Foundation; either version 2, or (at your option)
14 // any later version.
15 //
16 // The SC Toolkit is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU Library General Public License for more details.
20 //
21 // You should have received a copy of the GNU Library General Public License
22 // along with the SC Toolkit; see the file COPYING.LIB. If not, write to
23 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 //
25 // The U.S. Government is granted a limited license as per AL 91-7.
26 //
27
28 #ifdef __GNUG__
29 #pragma implementation
30 #endif
31
32 #ifdef HAVE_CONFIG_H
33 #include <scconfig.h>
34 #endif
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <sys/types.h>
40 #include <sys/ipc.h>
41 #include <sys/sem.h>
42 #include <util/group/globcnt.h>
43
44 using namespace sc;
45
46 #ifndef SEM_A
47 # define SEM_A 0200
48 #endif
49
50 #ifndef SEM_R
51 # define SEM_R 0400
52 #endif
53
GlobalCounter()54 GlobalCounter::GlobalCounter()
55 {
56 semid_ = -1;
57 controls_release_ = 0;
58 }
59
60 void
cleanup()61 GlobalCounter::cleanup()
62 {
63 if (semid_ != -1 && controls_release_) {
64 int ret;
65 #ifdef SEMCTL_REQUIRES_SEMUN
66 semun junk;
67 junk.val = 0;
68 #else
69 int junk = 0;
70 #endif
71 ret = semctl(semid_, 0, IPC_RMID, junk);
72 if (ret == -1) {
73 perror("semctl (IPC_RMID)");
74 abort();
75 }
76
77 semid_ = -1;
78 }
79 }
80
81 void
initialize()82 GlobalCounter::initialize()
83 {
84 cleanup();
85 semid_ = semget(IPC_PRIVATE, 1, IPC_CREAT | SEM_R | SEM_A );
86 if (semid_ == -1) {
87 perror("semget");
88 abort();
89 }
90 controls_release_ = 1;
91 operator = (0);
92 }
93
94 void
initialize(const char * stringrep)95 GlobalCounter::initialize(const char *stringrep)
96 {
97 semid_ = atoi(stringrep);
98 controls_release_ = 0;
99 }
100
~GlobalCounter()101 GlobalCounter::~GlobalCounter()
102 {
103 cleanup();
104 }
105
106 void
operator =(int i)107 GlobalCounter::operator = (int i)
108 {
109 #ifdef SEMCTL_REQUIRES_SEMUN
110 semun val;
111 val.val = i;
112 #else
113 int val = i;
114 #endif
115 if (semctl(semid_, 0, SETVAL, val) == -1) {
116 perror("semctl (SETVAL)");
117 abort();
118 }
119 }
120
121 int
val()122 GlobalCounter::val()
123 {
124 #ifdef SEMCTL_REQUIRES_SEMUN
125 semun val;
126 val.val = 0;
127 #else
128 int val = 0;
129 #endif
130 int ret;
131 if ((ret = semctl(semid_, 0, GETVAL, val)) == -1) {
132 perror("semctl (GETVAL)");
133 abort();
134 }
135 return ret;
136 }
137
138 void
wait_for_zero()139 GlobalCounter::wait_for_zero()
140 {
141 operator += (0);
142 }
143
144 void
operator +=(int i)145 GlobalCounter::operator+=(int i)
146 {
147 struct sembuf s;
148 s.sem_num = 0;
149 s.sem_op = i;
150 s.sem_flg = 0;
151 if (semop(semid_, &s, 1) == -1) {
152 perror("semop");
153 abort();
154 }
155 }
156
157 void
operator --()158 GlobalCounter::operator--()
159 {
160 operator += (-1);
161 }
162
163 void
operator ++()164 GlobalCounter::operator++()
165 {
166 operator += (1);
167 }
168
169 char *
stringrep()170 GlobalCounter::stringrep()
171 {
172 char tmp[80];
173 sprintf(tmp, "%d", semid_);
174 return strcpy(new char[strlen(tmp)+1], tmp);
175 }
176
177 /////////////////////////////////////////////////////////////////////////////
178
179 // Local Variables:
180 // mode: c++
181 // c-file-style: "CLJ"
182 // End:
183