source: Sophya/trunk/ArchTOIPipe/Kernel/toisegment.cc@ 2319

Last change on this file since 2319 was 2282, checked in by aubourg, 23 years ago

deadlock work

File size: 18.6 KB
RevLine 
[1738]1// ArchTOIPipe (C) CEA/DAPNIA/SPP IN2P3/LAL
2// Eric Aubourg
3// Christophe Magneville
4// Reza Ansari
[2282]5// $Id: toisegment.cc,v 1.28 2002-11-28 15:49:21 aubourg Exp $
[1738]6
[1670]7#include "toisegment.h"
[1671]8
[1759]9#include <iostream.h>
[1697]10
[1690]11#ifndef MAXINT
12#define MAXINT 2147483647
13#endif
14
[1692]15static pthread_mutex_t cout_mutex = PTHREAD_MUTEX_INITIALIZER;
16static void cout_lock() {pthread_mutex_lock(&cout_mutex);}
17static void cout_unlock() {pthread_mutex_unlock(&cout_mutex);}
[1711]18#define LOG(_xxx_)
19/*
[1692]20#define LOG(_xxx_) \
21cout_lock(); \
22_xxx_; \
23cout_unlock();
[1711]24*/
[1692]25
[1689]26/******************************/
27/******* TOISegmented *********/
28/******************************/
29
30TOISegmented::TOISegmented(int bufsz, int maxseg) {
[1710]31 master = new MasterView(bufsz, maxseg, "");
[1689]32 setName("TOISegmented");
[1740]33 syncOldWay = false;
[1689]34}
35
36TOISegmented::TOISegmented(string nm, int bufsz, int maxseg) {
[1710]37 master = new MasterView(bufsz, maxseg, nm);
[1689]38 setName(nm);
[1740]39 syncOldWay = false;
[1689]40}
41
[1699]42TOISegmented::TOISegmented(char* cnm, int bufsz, int maxseg) {
43 string nm = cnm;
[1710]44 master = new MasterView(bufsz, maxseg, nm);
[1699]45 setName(nm);
[1740]46 syncOldWay = false;
[1699]47}
48
[1689]49TOISegmented::~TOISegmented() {
50 delete master;
51}
52
53
[1692]54void TOISegmented::addConsumer(TOIProcessor* p) {
55 TOI::addConsumer(p);
56 master->nConsumers = consumers.size();
57}
58
59
[1689]60double TOISegmented::getData(int i) { /* reader thread */
61 return master->getData(i);
62}
63
64void TOISegmented::getData(int i, double& data, uint_8& flag) { /* reader thread */
65 data = master->getData(i);
66 flag = master->getFlag(i);
67}
68
[1743]69void TOISegmented::getData(int i, int n, double* data, uint_8* flg) { /* reader thread */
70 master->getData(i, n, data, flg);
71}
72
[1689]73void TOISegmented::putData(int i, double value, uint_8 flag) { /* writer thread */
74 master->putData(i, value, flag);
75}
76
[1743]77void TOISegmented::putData(int i, int n, double const* val, uint_8 const* flg) { /* writer thread */
78 master->putData(i, n, val, flg);
79}
80
[1689]81void TOISegmented::putDone() {
82 master->putDone();
83}
84
85void TOISegmented::wontNeedBefore(int i) { /* reader thread */
86 master->getView()->wontNeedBefore(i);
87}
88
89TOI::DataStatus TOISegmented::isDataAvail(int i, int j) {
90 // return master->getView()->isDataAvail(i, j);
91 cout << "TOISegmented::isDataAvail unimplemented" << endl;
92 throw PError("TOISegmented::isDataAvail unimplemented");
93}
94
95TOI::DataStatus TOISegmented::isDataAvail(int i) {
96 return isDataAvail(i,i);
97}
98
99TOI::DataStatus TOISegmented::isDataAvailNL(int i, int j) {
100 return isDataAvail(i,j);
101}
102
[1754]103TOI::DataStatus TOISegmented::isDataAvailNL(int i) {
104 return isDataAvail(i);
105}
106
[1689]107void TOISegmented::waitForData(int iStart, int iEnd) {
108 // get will wait...
109}
110
111void TOISegmented::waitForData(int i) {
112 // get will wait...
113}
114
115void TOISegmented::waitForAnyData() {
116 cout << "TOISegmented::waitForAnyData unimplemented" << endl;
117 throw PError("TOISegmented::waitForAnyData unimplemented");
118}
119
120int TOISegmented::nextDataAvail(int iAfter) {
121 cout << "TOISegmented::nextDataAvail" << endl;
122 return iAfter+1;
123}
124
125bool TOISegmented::hasSomeData() {
126 cout << "TOISegmented::hasSomeData" << endl;
127 return true;
128}
129
[1692]130void TOISegmented::doPutData(int i, double value, uint_8 flag) {
[1689]131 cout << "TOISegmented::doPutData unimplemented" << endl;
132 throw PError("TOISegmented::doPutData unimplemented");
133}
134
135void TOISegmented::doGetData(int i, double& value, uint_8& flag) {
136 cout << "TOISegmented::doGetData unimplemented" << endl;
137 throw PError("TOISegmented::doGetData unimplemented");
138}
139
140
[1686]141/*******************************/
142/******* BufferSegment *********/
143/*******************************/
[1671]144
145TOISegmented::BufferSegment::BufferSegment(int sz) {
146 status = NEW;
147 bufferSize = sz;
148 sn0 = -1;
149
150 refcount = 0;
151
152 data = new double[sz];
153 flags = new uint_8[sz];
154
155 pthread_mutex_init(&refcount_mutex, NULL);
156}
157
158TOISegmented::BufferSegment::~BufferSegment() {
159 if (refcount > 0) {
[1944]160 cerr << "TOISegment : delete Buffer with refcount>0" << endl;
[1671]161 throw(ForbiddenError("TOISegment : delete Buffer with refcount>0"));
162 }
[1700]163 LOG(cout << "Destroying buffersegment sn0 "<< sn0 << endl);
[1671]164 delete[] data;
165 delete[] flags;
166 pthread_mutex_destroy(&refcount_mutex);
167}
168
[1743]169void TOISegmented::BufferSegment::getData(int sn, int n, double* d, uint_8* f) {
170 checkCommitted();
171 checkInRange(sn);
172 checkInRange(sn+n-1);
173 memcpy(d, data+(sn-sn0), n*sizeof(double));
174 if (f != NULL) {
175 memcpy(f, flags+(sn-sn0), n*sizeof(uint_8));
176 }
177}
178
[1689]179void TOISegmented::BufferSegment::putData(int sn, double d, uint_8 f) {
180 /* writer thread*/
[1671]181 if (status == NEW) {
182 status = WRITE;
183 sn0 = sn;
184 }
185 if (status == COMMITTED) {
[1944]186 cerr << "TOISegment : putData in committed buffer" << endl;
[1671]187 throw(ForbiddenError("TOISegment : putData in committed buffer"));
188 }
189 checkInRange(sn);
190 data[sn-sn0] = d;
191 flags[sn-sn0] = f;
192}
193
[1743]194void TOISegmented::BufferSegment::putData(int sn, int n, double const* d, uint_8 const* f) {
[1744]195 if (status == NEW) {
196 status = WRITE;
197 sn0 = sn;
198 }
199 if (status == COMMITTED) {
[1944]200 cerr << "TOISegment : putData in committed buffer" << endl;
[1744]201 throw(ForbiddenError("TOISegment : putData in committed buffer"));
202 }
[1964]203 if (n==0) return;
[1743]204 checkInRange(sn);
205 checkInRange(sn+n-1);
206 memcpy(data+(sn-sn0), d, n*sizeof(double));
207 if (f != NULL) {
208 memcpy(flags+(sn-sn0), f, n*sizeof(uint_8));
209 } else {
210 memset(flags+(sn-sn0), 0, n*sizeof(uint_8));
211 }
212}
213
[1671]214void TOISegmented::BufferSegment::incRefCount() {
215 pthread_mutex_lock(&refcount_mutex);
216 refcount++;
217 pthread_mutex_unlock(&refcount_mutex);
218}
219
220void TOISegmented::BufferSegment::decRefCount() {
221 pthread_mutex_lock(&refcount_mutex);
222 int nrc = --refcount;
223 pthread_mutex_unlock(&refcount_mutex);
[1944]224 if (nrc<0) {
225 cerr << "TOISegment : buffer refcount < 0" << endl;
[1671]226 throw(ForbiddenError("TOISegment : buffer refcount < 0"));
[1944]227 }
[1671]228}
229
230int TOISegmented::BufferSegment::getRefCount() {
231 pthread_mutex_lock(&refcount_mutex);
232 int rc = refcount;
233 pthread_mutex_unlock(&refcount_mutex);
234 return rc;
235}
236
[1686]237
238/*******************************/
239/********** BufferView *********/
240/*******************************/
241
242TOISegmented::BufferView::BufferView(MasterView* m) {
243 master = m;
244 sn0 = -1;
245 segmentSize = m->segmentSize;
[1689]246 firstNeeded = -1;
[1692]247 waiting = false;
[1773]248 waitingFor = -1;
[1686]249}
250
251TOISegmented::BufferView::~BufferView() {
252}
253
[1692]254double TOISegmented::BufferView::getData(int sn) { /* Single-thread, reader thread*/
[1686]255 ensure(sn);
256 int seg = (sn-sn0)/segmentSize;
257 return segments[seg]->getData(sn);
258}
259
[1692]260uint_8 TOISegmented::BufferView::getFlag(int sn) { /* Single-thread, reader thread */
[1686]261 ensure(sn);
262 int seg = (sn-sn0)/segmentSize;
263 return segments[seg]->getFlag(sn);
264}
265
[1743]266void TOISegmented::BufferView::getData(int sn, int n, double* dat, uint_8* flg) { /* Single-thread, reader thread */
267 ensure(sn);
268 ensure(sn+n-1);
269
270 int sn1 = sn;
271 int nsam = n;
272 double* pdat = dat;
273 uint_8* pflg = flg;
274
275 while (true) {
276 int seg = (sn1-sn0)/segmentSize;
277 BufferSegment* s = segments[seg];
278 int snmax = s->sn0 + s->bufferSize - 1;
279 int sn2 = snmax > (sn1+nsam-1) ? (sn1+nsam-1) : snmax;
280 int nget = sn2-sn1+1;
281 s->getData(sn1, nget, pdat, pflg);
282 pdat += nget;
283 if (pflg != NULL) pflg += nget;
284 nsam -= nget;
285 sn1 += nget;
286 if (nsam <= 0) break;
287 }
288}
289
[1692]290void TOISegmented::BufferView::ensure(int sn) { /* Single-thread, reader thread */
[1686]291 if (sn < sn0) {
[2282]292 cout << "TOISegmented::BufferView::ensure : requested sample before first" << endl;
[1750]293 cout << "sn " << sn << " sn0 " << sn0 << endl;
[2282]294 cout << "name : " << master->name << endl;
[1692]295 abort();
[1686]296 }
297
[1692]298 if (sn0 < 0 ||
299 sn >= sn0 + segmentSize*segments.size()) {
[1710]300 LOG(cout << master->name << " BufferView "
301 << hex << this << dec << ": read fault for " << sn << endl)
[1686]302 sync();
[1709]303 pthread_mutex_lock(&(master->read_wait_mutex));
[1692]304 while (sn0<0 || sn >= sn0 + segmentSize*segments.size()) {
[1773]305 wait(sn); // must be atomic with loop test // $CHECK$ est-ce vrai ?
[1709]306 pthread_mutex_unlock(&(master->read_wait_mutex));
[1710]307 LOG(cout << master->name << " BufferView " << hex << this << dec << ": waiting for " << sn << endl)
[1686]308 sync();
[1709]309 pthread_mutex_lock(&(master->read_wait_mutex));
[1686]310 }
[1709]311 pthread_mutex_unlock(&(master->read_wait_mutex));
312
[1710]313 LOG(cout << master->name << " BufferView " << hex << this << dec << ": resuming for " << sn
[1692]314 << " now data for " << sn0 << " - " << sn0 + segmentSize*segments.size()
315 << " in " << segments.size() << " segments " << endl)
[1686]316 }
317}
318
[1692]319void TOISegmented::BufferView::sync() { /* Single-thread, reader thread */
[1686]320 master->updateView(this); // update me !
321}
322
[1773]323void TOISegmented::BufferView::wait(int sn) { /* reader thread, master read wait lock taken */
[1709]324 //pthread_mutex_lock(&(master->read_wait_mutex));
[1692]325 waiting = true;
[1773]326 waitingFor = sn;
[1711]327 master->waitingViews++;
[1692]328 pthread_cond_wait(&(master->read_wait_condv), &(master->read_wait_mutex));
329 waiting = false;
[1773]330 waitingFor = -1;
[1711]331 master->waitingViews--;
[1709]332 //pthread_mutex_unlock(&(master->read_wait_mutex));
[1686]333}
334
335
[1689]336void TOISegmented::BufferView::wontNeedBefore(int sn) { /* reader thread */
337 if (sn > firstNeeded) {
338 firstNeeded = sn;
[1711]339 // C'est peut-etre le moment de faire unl sync, si on est coince par ailleurs...
340 //pthread_mutex_lock(&(master->read_wait_mutex));
341 if (sn >= sn0 + segmentSize){ // && master->waitingViews>0) {
342// LOG(cout<<master->name<< " sync on wontneed, waitingViews=" << master->waitingViews << endl);
343 LOG(cout<<master->name<< " sync on wontneed, sn = " << sn << " sn0 = " << sn0 << endl);
344 sync();
345 }
346 //pthread_mutex_unlock(&(master->read_wait_mutex));
[1689]347 }
348}
[1686]349
[1689]350
[1686]351/*******************************/
352/********** MasterView *********/
353/*******************************/
354
[1710]355TOISegmented::MasterView::MasterView(int bufsz, int maxseg, string nm) {
[1686]356 currentSegment = NULL;
357 maxSegments = maxseg;
358 segmentSize = bufsz;
359 sn0 = -1;
[1692]360 nConsumers = 0;
[1710]361 name = nm;
[1686]362
363 pthread_mutex_init(&views_mutex, NULL);
[1692]364 pthread_mutex_init(&read_wait_mutex, NULL);
365 pthread_cond_init(&write_wait_condv, NULL);
366 pthread_cond_init(&read_wait_condv, NULL);
[1686]367 pthread_key_create(&buffer_key, BufferDestroy);
368
[1689]369 waitingOnWrite = false;
[1711]370 waitingViews = 0;
[1686]371}
372
373TOISegmented::MasterView::~MasterView() {
374 pthread_mutex_destroy(&views_mutex);
[1692]375 pthread_mutex_destroy(&read_wait_mutex);
376 pthread_cond_destroy(&write_wait_condv);
377 pthread_cond_destroy(&read_wait_condv);
[1686]378 pthread_key_delete(buffer_key);
379
380 // There should not be any BufferView left... Check ?
381
382 // decrement count for segments ?
383}
384
[1692]385void TOISegmented::MasterView::putData(int sn, double data, uint_8 flags) { /* writer thread */
386 if (sn0<0) {
[1750]387 LOG(cout << "***MasterView::putData sn0<0 -> " << sn << endl);
[1692]388 sn0=sn;
389 }
[1686]390 // can fit in current segment ?
391 if (!(currentSegment != NULL &&
392 sn >= currentSegment->sn0 &&
393 sn < currentSegment->sn0 + currentSegment->bufferSize)) {
[1710]394 LOG(cout << name << " MasterView::putData, need extend for " << sn << endl)
[1686]395 nextSegment();
396 }
397 currentSegment->putData(sn, data, flags);
398}
399
[1743]400void TOISegmented::MasterView::putData(int sn, int n, double const* data, uint_8 const* flags) { /* writer thread */
401 if (sn0<0) {
[1750]402 LOG(cout << "***MasterView::putData sn0<0 -> " << sn << endl);
[1743]403 sn0=sn;
404 }
405 double const* pdat = data;
406 uint_8 const* pflg = flags;
407 int nsam = n;
408 int sn1 = sn;
409 while (true) {
410 // maximum that current segment can take
411 int snmax = -1;
412 if (currentSegment != NULL) {
413 snmax = currentSegment->sn0 + currentSegment->bufferSize-1;
414 }
415 int sn2 = snmax > (sn1+nsam-1) ? (sn1+nsam-1) : snmax;
[1964]416 int nput = sn2-sn1+1;
417 if (snmax>0 && nput>0) {
[1743]418 currentSegment->putData(sn1, nput, pdat, pflg);
419 pdat += nput;
420 if (pflg != NULL) pflg += nput;
421 nsam -= nput;
422 sn1 += nput;
423 }
424 if (nsam <= 0) break;
425 nextSegment();
426 currentSegment->putData(sn1, 0, 0); // dummy, to initialize sn0 in segment : add method ?
427 }
428}
429
[1692]430double TOISegmented::MasterView::getData(int sn) { /* reader thread */
431 return getView()->getData(sn); /* thread-specific */
[1686]432}
433
[1692]434uint_8 TOISegmented::MasterView::getFlag(int sn) { /* reader thread */
[1686]435 return getView()->getFlag(sn);
436}
437
[1743]438void TOISegmented::MasterView::getData(int sn, int n, double* dat, uint_8* flg) { /* reader thread */
439 getView()->getData(sn, n, dat, flg);
440}
441
[1686]442TOISegmented::BufferView* TOISegmented::MasterView::getView() { /* reader thread */
443 BufferView* bv = (BufferView*) pthread_getspecific(buffer_key);
444 if (bv == NULL) {
445 bv = createView();
[1692]446 LOG(cout << "creating new view " << hex << bv << dec << endl)
[1686]447 pthread_setspecific(buffer_key, bv);
448 }
449 return bv;
450}
[1689]451
[1692]452void TOISegmented::MasterView::signalWaitingViews() { /* any thread */ /* views locked */
453 pthread_mutex_lock(&read_wait_mutex);
454 pthread_cond_broadcast(&read_wait_condv);
455 pthread_mutex_unlock(&read_wait_mutex);
456}
[1689]457
[1692]458void TOISegmented::MasterView::signalWrite() { /* reader thread */ /* views locked */
459 if (waitingOnWrite) {
[1710]460 LOG(cout << name << " MasterView : signal for wait on write" << endl)
[1692]461 pthread_cond_signal(&write_wait_condv); // only one thread can be sleeping
[1689]462 }
463}
464
465void TOISegmented::MasterView::putDone() {
466 nextSegment(); // cree un segment inutile, a nettoyer
467}
468
469void TOISegmented::MasterView::nextSegment() { /* writer thread */
470 // The current segment, if any, is now committed. A new
471 // blank buffer is allocated, if any.
[1692]472 pthread_mutex_lock(&views_mutex);
[1689]473
[1692]474 LOG(cout << "MasterView::nextSegment "
475 << segments.size()+1 << "/" << maxSegments << endl)
[1689]476
477 if (currentSegment != NULL) {
478 currentSegment->status = BufferSegment::COMMITTED;
479 segments.push_back(currentSegment);
480 }
481
482 currentSegment = NULL;
483 while (segments.size() >= maxSegments) {
484 waitForCleaning();
485 }
486
487 currentSegment = new BufferSegment(segmentSize);
[1700]488 currentSegment->incRefCount();
[1689]489 signalWaitingViews(); // they can ask to be updated !!
[1692]490 pthread_mutex_unlock(&views_mutex);
[1689]491}
492
[1692]493void TOISegmented::MasterView::waitForCleaning() { /* writer thread */ /* views locked */
[1710]494 LOG(cout << name << " MasterView : write wait for clean for " << sn0 << endl)
[1689]495 waitingOnWrite = true;
496 checkDeadLock();
[1692]497 pthread_cond_wait(&write_wait_condv, &views_mutex);
[1710]498 LOG(cout << name << " MasterView : wait done" << endl)
[1689]499}
500
501TOISegmented::BufferView* TOISegmented::MasterView::createView() { /* reader thread */
502 BufferView* bv = new BufferView(this);
[1692]503 pthread_mutex_lock(&views_mutex);
[1690]504 allViews.insert(bv);
[1692]505 pthread_mutex_unlock(&views_mutex);
[1689]506 updateView(bv);
507 return bv;
508}
509
510void TOISegmented::MasterView::updateView(BufferView* bv) { /* reader thread */
511 pthread_mutex_lock(&views_mutex);
512
[1711]513// int oldBegin = bv->sn0;
514// int oldEnd = bv->sn0 + bv->segmentSize * bv->segments.size();
515 int oldBegin = sn0;
516 int oldEnd = sn0 + bv->segmentSize * segments.size();
[1689]517
518 for (vector<BufferSegment*>::iterator i = bv->segments.begin();
519 i != bv->segments.end(); i++) {
520 (*i)->decRefCount();
521 }
522
523 bv->segments.clear();
524
[1690]525 // utiliser firstNeeded de toutes les vues pour faire le menage chez
[1689]526 // nous.
[1690]527
[1692]528 // A condition que tous les consumers se soient fait connaitre...
[1689]529
[1692]530 if (nConsumers == allViews.size()) {
531 int firstNeeded = MAXINT;
532 for (set<BufferView*>::iterator i = allViews.begin();
533 i != allViews.end(); i++) {
[1711]534 LOG(cout << name << " View firstneeded " << (*i)->firstNeeded << endl);
[1692]535 if ((*i)->firstNeeded < firstNeeded) firstNeeded = (*i)->firstNeeded;
536 }
537
[1710]538 LOG(cout << name << " MasterView : firstNeeded = " << firstNeeded << endl);
[1692]539
540 vector<BufferSegment*>::iterator j = segments.begin();
541 bool clean = false;
[1763]542 {for (vector<BufferSegment*>::iterator i = segments.begin();
[1692]543 i != segments.end(); i++) {
[1700]544 //LOG(cout << "Updating : rc = " << (*i)->getRefCount() << " sn0 = " << (*i)->sn0 << endl;);
545 if (((*i)->sn0+(*i)->bufferSize <= firstNeeded) && ((*i)->getRefCount() == 1)) {
[1692]546 clean = true;
[1700]547 (*i)->decRefCount();
548 delete (*i);
[1692]549 j = i;
550 }
[1763]551 }}
[1700]552 j++;
[1690]553 if (clean) {
554 segments.erase(segments.begin(),j);
555 sn0 = (*segments.begin())->sn0;
[1692]556 LOG(cout << "MasterView : purged until " << sn0 << endl);
[1690]557 }
[1692]558 } else {
559 LOG(cout << "MasterView : not yet all consumer thread known "<< allViews.size()
560 << "/" << nConsumers << endl);
561 }
[1690]562
[1763]563 {for (vector<BufferSegment*>::iterator i = segments.begin();
[1689]564 i != segments.end(); i++) {
565 if ( (*i)->sn0+(*i)->bufferSize > bv->firstNeeded ) {
566 (*i)->incRefCount();
567 bv->segments.push_back(*i);
568 }
[1763]569 }}
[1689]570
571 bv->sn0 = -1;
572 int newEnd = -1;
573 if (segments.size() > 0) {
574 bv->sn0 = bv->segments[0]->sn0;
575 newEnd = bv->sn0 + bv->segmentSize * bv->segments.size();
576 }
577
[1711]578 if (sn0 > oldBegin) { // nettoyage de fait, reveiller le writer thread si besoin
[1692]579 signalWrite();
[1689]580 }
581
[1710]582 LOG(cout << name << " sync for " << hex << bv << dec << " : "
[1692]583 << oldBegin << " - " << oldEnd << " --> "
[1711]584 << sn0 << " - " << newEnd << endl);
[1692]585
586 if (newEnd > oldEnd) { // Nouveautes, reveiller les reader threads si besoin
[1689]587 signalWaitingViews();
588 }
[1692]589 pthread_mutex_unlock(&views_mutex);
[1689]590}
591
[1692]592void TOISegmented::MasterView::checkDeadLock() { /* views locked */
[1689]593 // There is a possible deadlock if no view can free old segments
594 // and we are waiting for write.
595
596 // we need to record "wont need before" for each view, and
597 // signal deadlock if any view that needs first segment data is sleeping
598 // while we are asleep
599
[1692]600 pthread_mutex_lock(&read_wait_mutex);
601 if (!waitingOnWrite) {
602 pthread_mutex_unlock(&read_wait_mutex);
603 return; // no problem, there is an active writer
604 }
[1689]605
606 // Is any sleeping view needing our first segment ?
607
[1692]608 for (set<BufferView*>::iterator i=allViews.begin();
609 i != allViews.end(); i++) {
610 if ((*i)->waiting && (*i)->firstNeeded < sn0+segmentSize) {
[1689]611 cout << "**** DEADLOCK detected ****" << endl;
612 cout << "We are waiting on write (buffer is full)"<< endl;
613 cout << "but a waiting reader still needs our first segment" << endl;
614 cout << "restart with bigger buffers" << endl;
[1775]615
616 cout << "master has range " << sn0 << " - "
617 << sn0+segments.size()*segmentSize-1 <<endl;
618 cout << "in " << segments.size() << " segments" << endl;
619 cout << "waiting bufferview is waiting for " << (*i)->waitingFor
620 << " and still needs " << (*i)->firstNeeded << endl;
[1804]621 cout << "it has sn0= " << (*i)->sn0 << " nseg = " << (*i)->segments.size()
622 << " snlast = " << (*i)->sn0+(*i)->segments.size()*(*i)->segmentSize -1
623 << endl;
624
[2282]625 cout << "lets try something before failing, but the program may block" << endl;
626 pthread_cond_broadcast(&read_wait_condv);
627 //usleep(1000);
628 // abort();
[1689]629 }
630 }
[1692]631 pthread_mutex_unlock(&read_wait_mutex);
[1689]632}
633
634
635
636void TOISegmented::MasterView::BufferDestroy(void* p) {
637 BufferView* bv = (BufferView*) p;
638 delete bv;
639}
Note: See TracBrowser for help on using the repository browser.