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