source: Sophya/trunk/ArchTOIPipe/Kernel/toiprocessor.cc@ 1740

Last change on this file since 1740 was 1740, checked in by aubourg, 24 years ago

une optim pour quand on n'a que des segmented

File size: 10.1 KB
Line 
1// ArchTOIPipe (C) CEA/DAPNIA/SPP IN2P3/LAL
2// Eric Aubourg
3// Christophe Magneville
4// Reza Ansari
5// $Id: toiprocessor.cc,v 1.14 2001-11-08 23:23:58 aubourg Exp $
6
7#include "toiprocessor.h"
8#include "toimanager.h"
9#include <pthread.h>
10
11#ifdef HAVE_VALUES_H
12#include <values.h>
13#endif
14
15#ifndef MAXINT
16#define MAXINT 2147483647
17#endif
18
19#ifdef HAVE_STDINT_H
20#include <stdint.h>
21#endif
22
23#ifdef WITH_SOPHYA
24#include "pexceptions.h"
25#else
26#include "apexceptions.h"
27#endif
28
29#define pthread_mutexattr_setkind_np pthread_mutexattr_settype
30
31TOIProcessor::TOIProcessor() {
32 //cout << "TOIProcessor::TOIProcessor" << endl;
33 outTOIs = NULL;
34 inTOIs = NULL;
35 inited=false;
36
37 upExtra = 0;
38 lowExtra = 0;
39 minOut = -1;
40 maxOut = -1;
41 neededHistory = 1000;
42 lastAWN = 0;
43 wontNeedValue = -1;
44
45}
46
47TOIProcessor::~TOIProcessor() {
48 delete[] outTOIs;
49 delete[] inTOIs;
50 //if (mutex)
51 pthread_mutex_destroy(&mutex);
52 //if (dataReady)
53 pthread_cond_destroy(&dataReady);
54 pthread_detach(thread);
55}
56
57
58void TOIProcessor::init() {
59 //cout << "TOIProcessor::init" << endl;
60}
61
62void TOIProcessor::afterinit() {
63 int i;
64 inTOIs = new (TOI*[inIx.size()]);
65 for(i=0; i<inIx.size(); i++)
66 inTOIs[i] = NULL; // Protection-Initialisation - Reza 11/3/2001
67 outTOIs = new (TOI*[outIx.size()]);
68 for(i=0; i<outIx.size(); i++)
69 outTOIs[i] = NULL; // Protection-Initialisation - Reza 11/3/2001
70}
71
72int TOIProcessor::getMinOut() {
73 //cout << name << "minout" << endl;
74 if (minOut < 0) minOut = calcMinOut();
75 //cout << name << "minout=" << minOut << endl;
76 return minOut;
77}
78
79int TOIProcessor::getMaxOut() {
80 //cout << name << "maxout" << endl;
81 if (maxOut < 0) maxOut = calcMaxOut();
82 //cout << name << "maxout=" << maxOut << endl;
83 return maxOut;
84}
85
86int TOIProcessor::calcMinOut() {
87 return getMinIn() + lowExtra;
88}
89
90int TOIProcessor::calcMaxOut() {
91 return getMaxIn() - upExtra;
92}
93
94int TOIProcessor::getMinIn() {
95 int nIn = inIx.size();
96 int minIn = 0;
97 for (int i=0; i<nIn; i++) {
98 TOI* toi = inTOIs[i];
99 if (toi == NULL) continue; // Protection - Reza 13/3/2001
100 int x = toi->getMinSn();
101 if (x > minIn) minIn = x;
102 }
103 return minIn;
104}
105
106int TOIProcessor::getMaxIn() {
107 int_4 nIn = inIx.size();
108 int_4 maxIn = MAXINT;
109 for (int i=0; i<nIn; i++) {
110 TOI* toi = inTOIs[i];
111 if (toi == NULL) continue; // Protection - Reza 13/3/2001
112 int_4 x = toi->getMaxSn();
113 if (x < maxIn) maxIn = x;
114 }
115 return maxIn;
116}
117
118
119int TOIProcessor::declareInput(string toi) {
120 if (inIx.find(toi) != inIx.end())
121 throw DuplicateIdExc("TOIProcessor::declareInput : "+toi+" already declared");
122 int i = inIx.size();
123 inIx[toi] = i;
124 return i;
125}
126
127int TOIProcessor::declareOutput(string toi) {
128 if (outIx.find(toi) != outIx.end())
129 throw DuplicateIdExc("TOIProcessor::declareInput : "+toi+" already declared");
130 int i = outIx.size();
131 outIx[toi] = i;
132 return i;
133}
134
135int TOIProcessor::getInputTOIIndex(string toi) {
136 chkinit();
137 map<string, int>::iterator i = inIx.find(toi);
138 if (i == inIx.end()) return -1;
139 return (*i).second;
140}
141
142int TOIProcessor::getOutputTOIIndex(string toi) {
143 chkinit();
144 map<string, int>::iterator i = outIx.find(toi);
145 if (i == outIx.end()) return -1;
146 return (*i).second;
147}
148
149// Methodes rajoutees par Reza 11/3/2001
150TOI* TOIProcessor::getInputTOI(int toiIndex) {
151 // chkinit();
152 if (toiIndex >= inIx.size())
153 throw RangeCheckError("TOIProcessor::getInputTOI() out of bound toiIndex");
154 TOI* toi = inTOIs[toiIndex];
155 if (toi == NULL)
156 throw NullPtrError("TOIProcessor::getInputTOI() - Not assigned TOI !");
157 return(toi);
158}
159
160TOI* TOIProcessor::getOutputTOI(int toiIndex) {
161 // chkinit();
162 if (toiIndex >= outIx.size())
163 throw RangeCheckError("TOIProcessor::getOutputTOI() out of bound toiIndex");
164 TOI* toi = outTOIs[toiIndex];
165 if (toi == NULL)
166 throw NullPtrError("TOIProcessor::getOutputTOI() - Not assigned TOI !");
167 return(toi);
168}
169
170bool TOIProcessor::checkInputTOIIndex(int toiIndex) {
171 if (toiIndex >= inIx.size()) return false;
172 if (inTOIs[toiIndex] == NULL) return false;
173 return true;
174}
175
176bool TOIProcessor::checkOutputTOIIndex(int toiIndex) {
177 if (toiIndex >= outIx.size()) return false;
178 if (outTOIs[toiIndex] == NULL) return false;
179 return true;
180}
181
182void TOIProcessor::PrintStatus(ostream & os)
183{
184 chkinit();
185 os << " TOIProcessor::PrintStatus() - Name= " << name
186 << " MinIn=" << getMinIn() << " MaxIn=" << getMaxIn() << endl;
187 os << " --- Inputs N= " << inIx.size() << endl;
188 int k;
189 for(k=0; k<inIx.size(); k++) {
190 os << "Input[" << k << "] : " << getInName(k) ;
191 if (inTOIs[k] != NULL)
192 os << " Connected TOI " << inTOIs[k]->getName() << endl;
193 else os << " NO TOI " << endl;
194 }
195 os << " --- Outputs N= " << outIx.size() << endl;
196 for(k=0; k<outIx.size(); k++) {
197 os << "Output[" << k << "] : " << getOutName(k) ;
198 if (outTOIs[k] != NULL)
199 os << " Connected TOI " << outTOIs[k]->getName() << endl;
200 else os << " NO TOI " << endl;
201 }
202 os << endl;
203 return;
204}
205
206// Fin rajout Reza 11/3/2001
207
208void TOIProcessor::addInput(string name, TOI* toi) {
209 chkinit();
210 map<string, int>::iterator i = inIx.find(name);
211 if (i == inIx.end()) throw NotFoundExc("TOIProcessor::addInput "+
212 name+" not declared");
213 inTOIs[(*i).second] = toi;
214 toi->addConsumer(this); // $CHECK$ Reza 13/3/2001
215}
216
217void TOIProcessor::addOutput(string name, TOI* toi) {
218 chkinit();
219 map<string, int>::iterator i = outIx.find(name);
220 if (i == outIx.end()) throw NotFoundExc("TOIProcessor::addOutput "+
221 name+" not declared");
222 toi->setProducer(this);
223 outTOIs[(*i).second] = toi;
224}
225
226string TOIProcessor::getOutName(int i) {
227 if (i > outIx.size()) throw RangeCheckError("TOIProcessor::getOutName "
228 " out of bound");
229 map<string, int>::iterator j;
230 for(j=outIx.begin(); j!= outIx.end(); j++)
231 if ((*j).second == i) return (*j).first;
232
233 throw RangeCheckError("TOIProcessor::getOutName Not found index !");
234}
235
236string TOIProcessor::getInName(int i) {
237 if (i > inIx.size()) throw RangeCheckError("TOIProcessor::getInName "
238 " out of bound");
239 map<string, int>::iterator j;
240 for(j=inIx.begin(); j!= inIx.end(); j++)
241 if ((*j).second == i) return (*j).first;
242
243 throw RangeCheckError("TOIProcessor::getOutName Not found index !");
244}
245
246void TOIProcessor::run() {
247
248}
249
250void TOIProcessor::warnPutDone() {
251 int n = outIx.size();
252 for (int i=0; i<n; i++) {
253 TOI* toi = outTOIs[i];
254 if (toi) {
255 toi->putDone();
256 }
257 }
258}
259
260void* TOIProcessor::ThreadStart(void* arg) {
261 TOIProcessor* p = (TOIProcessor*) arg;
262 // cout << p->name << " new thread running " << pthread_self() << endl;
263 p->run();
264 p->warnPutDone();
265 pthread_exit(NULL);
266 // cout << p->name << " thread done " << pthread_self() << endl;
267 return NULL;
268}
269
270#ifdef Linux
271#define pthread_mutexattr_settype pthread_mutexattr_setkind_np
272#define PTHREAD_MUTEX_ERRORCHECK PTHREAD_MUTEX_ERRORCHECK_NP
273#define pthread_mutex_setname_np(a,b,c)
274#define pthread_cond_setname_np(a,b,c)
275#endif
276
277void TOIProcessor::start() {
278 pthread_cond_init(&dataReady, NULL);
279 pthread_mutexattr_init(&mutattr);
280 // pthread_mutexattr_settype(&mutattr, PTHREAD_MUTEX_ERRORCHECK);
281 pthread_mutex_init(&mutex, &mutattr);
282 //pthread_mutex_setname_np(&mutex, (name + "_proc_mutex").c_str(), 0);
283 //pthread_cond_setname_np(&dataReady, (name + "_proc_cond").c_str(), 0);
284 //cout << name << " starting thread " << &thread << endl;
285 pthread_create(&thread, NULL, ThreadStart, this);
286 TOIManager::getManager()->addThread(&thread);
287}
288
289#ifndef NO_SOPHYA
290/* ---- l'interface va etre modifiee, NE PAS UTILISER
291Array TOIProcessor::getData(int toiIndex, int iStart, int iEnd) {
292 TOI* toi = getInputTOI(toiIndex);
293 toi->waitForData(iStart, iEnd);
294 return toi->getData(iStart, iEnd);
295}
296
297Array TOIProcessor::getError(int toiIndex, int iStart, int iEnd) {
298 TOI* toi = getInputTOI(toiIndex);
299 toi->waitForData(iStart, iEnd);
300 return toi->getError(iStart, iEnd);
301}
302
303TArray<int_4> TOIProcessor::getFlag(int toiIndex, int iStart, int iEnd) {
304 TOI* toi = getInputTOI(toiIndex);
305 toi->waitForData(iStart, iEnd);
306 return toi->getFlag(iStart, iEnd);
307}
308 l'interface va etre modifiee, NE PAS UTILISER ---- */
309#endif
310
311double TOIProcessor::getData(int toiIndex, int i) {
312 TOI* toi = getInputTOI(toiIndex);
313 if (toi->needSyncOldWay()) toi->waitForData(i); // seulement pour autre que segmented
314 autoWontNeed(i);
315 return toi->getData(i);
316}
317
318void TOIProcessor::getData(int toiIndex, int i, double &data, uint_8 &flag)
319{
320 TOI* toi = getInputTOI(toiIndex);
321 if (toi->needSyncOldWay()) toi->waitForData(i); // seulement pour autre que segmented
322 toi->getData(i, data, flag);
323 return;
324}
325
326/*RZCMV
327double TOIProcessor::getError(int toiIndex, int i) {
328 TOI* toi = getInputTOI(toiIndex);
329 toi->waitForData(i);
330 return toi->getError(i);
331}
332
333int_4 TOIProcessor::getFlag(int toiIndex, int i) {
334 TOI* toi = getInputTOI(toiIndex);
335 toi->waitForData(i);
336 return toi->getFlag(i);
337}
338*/
339
340void TOIProcessor::setNeededHistory(int nsamples) {
341 neededHistory = nsamples;
342}
343
344void TOIProcessor::wontNeedBefore(int i) {
345 if (i<wontNeedValue) return;
346 wontNeedValue = i;
347 for (int j=0; j< (int) inIx.size(); j++) {
348 // $CHECK$ Reza 6/5/2001 Protection sur non connected TOI
349 if (inTOIs[j]) inTOIs[j]->wontNeedBefore(i);
350 }
351}
352
353void TOIProcessor::autoWontNeed(int iCur) {
354 if (neededHistory <=0) return;
355 if (iCur < lastAWN + neededHistory) return;
356 lastAWN = iCur;
357 //cout << name << " wontNeedBefore " << iCur-neededHistory << endl;
358 wontNeedBefore(iCur-neededHistory);
359}
360
361void TOIProcessor::notify() {
362 lock();
363 pthread_cond_broadcast(&dataReady);
364 unlock();
365}
366
367
368void TOIProcessor::putData(int toiIndex, int i, double value, uint_8 flg) {
369 TOI* toi = getOutputTOI(toiIndex);
370 toi->putData(i, value, flg);
371 autoWontNeed(i);
372 if (toi->needSyncOldWay()) notify(); // seulement pour non segmented
373}
374
375/*RZCMV
376void TOIProcessor::putDataError(int toiIndex, int i, double value,
377 double error, int_4 flg) {
378 TOI* toi = getOutputTOI(toiIndex);
379 if (toi == NULL)
380 throw NullPtrError("TOIProcessor::putDataError() - Not assigned TOI !");
381 toi->putDataError(i, value, error, flg);
382 autoWontNeed(i);
383 notify();
384}
385*/
386
Note: See TracBrowser for help on using the repository browser.