Changeset 1686 in Sophya for trunk/ArchTOIPipe/Kernel/toisegment.cc
- Timestamp:
- Oct 12, 2001, 1:17:10 AM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/ArchTOIPipe/Kernel/toisegment.cc
r1671 r1686 1 1 #include "toisegment.h" 2 2 3 3 /*******************************/ 4 4 /******* BufferSegment *********/ 5 /*******************************/ 6 5 7 TOISegmented::BufferSegment::BufferSegment(int sz) { 6 8 status = NEW; … … 24 26 pthread_mutex_destroy(&refcount_mutex); 25 27 } 26 27 28 28 29 void TOISegmented::BufferSegment::putData(int sn, double d, uint_8 f) { … … 60 61 } 61 62 63 64 /*******************************/ 65 /********** BufferView *********/ 66 /*******************************/ 67 68 TOISegmented::BufferView::BufferView(MasterView* m) { 69 master = m; 70 sn0 = -1; 71 segmentSize = m->segmentSize; 72 pthread_mutex_init(&mutex, NULL); 73 pthread_cond_init(&condv, NULL); 74 } 75 76 TOISegmented::BufferView::~BufferView() { 77 pthread_mutex_destroy(&mutex); 78 pthread_cond_destroy(&condv); 79 } 80 81 double TOISegmented::BufferView::getData(int sn) { /* Single-thread */ 82 ensure(sn); 83 int seg = (sn-sn0)/segmentSize; 84 return segments[seg]->getData(sn); 85 } 86 87 uint_8 TOISegmented::BufferView::getFlag(int sn) { /* Single-thread */ 88 ensure(sn); 89 int seg = (sn-sn0)/segmentSize; 90 return segments[seg]->getFlag(sn); 91 } 92 93 void TOISegmented::BufferView::ensure(int sn) { /* Single-thread */ 94 if (sn < sn0) { 95 throw RangeCheckError("requested sample before first"); 96 } 97 98 if (sn >= sn0 + segmentSize*segments.size()) { 99 cout << "BufferView : read fault for " << sn << endl; 100 sync(); 101 while (sn >= sn0 + segmentSize*segments.size()) { 102 wait(); 103 cout << "BufferView : waiting for " << sn << endl; 104 sync(); 105 } 106 cout << "BufferView : resuming for " << sn << endl; 107 } 108 } 109 110 void TOISegmented::BufferView::sync() { /* Single-thread */ 111 master->updateView(this); // update me ! 112 } 113 114 void TOISegmented::BufferView::wait() { /* From reader thread */ 115 pthread_mutex_lock(&mutex); 116 master->addToWaitList(this); // needing wake-up call 117 pthread_cond_wait(&condv, &mutex); 118 pthread_mutex_unlock(&mutex); 119 } 120 121 void TOISegmented::BufferView::signal() { /* From masterview, writer thread */ 122 pthread_mutex_lock(&mutex); 123 pthread_cond_signal(&condv); // only one thread can be sleeping 124 master->removeFromWaitList(this); 125 pthread_mutex_unlock(&mutex); 126 } 127 128 129 /*******************************/ 130 /********** MasterView *********/ 131 /*******************************/ 132 133 TOISegmented::MasterView::MasterView(int bufsz, int maxseg) { 134 currentSegment = NULL; 135 maxSegments = maxseg; 136 segmentSize = bufsz; 137 sn0 = -1; 138 139 pthread_mutex_init(&views_mutex, NULL); 140 pthread_mutex_init(&write_mutex, NULL); 141 pthread_cond_init(&condv, NULL); 142 pthread_key_create(&buffer_key, BufferDestroy); 143 144 waitStatus = NO_WAIT; 145 } 146 147 TOISegmented::MasterView::~MasterView() { 148 pthread_mutex_destroy(&views_mutex); 149 pthread_mutex_destroy(&write_mutex); 150 pthread_cond_destroy(&condv); 151 pthread_key_delete(buffer_key); 152 153 // There should not be any BufferView left... Check ? 154 155 // decrement count for segments ? 156 } 157 158 void TOISegmented::MasterView::putData(int sn, double data, uint_8 flags) { 159 // can fit in current segment ? 160 if (!(currentSegment != NULL && 161 sn >= currentSegment->sn0 && 162 sn < currentSegment->sn0 + currentSegment->bufferSize)) { 163 nextSegment(); 164 } 165 currentSegment->putData(sn, data, flags); 166 } 167 168 double TOISegmented::MasterView::getData(int sn) { 169 return getView()->getData(sn); 170 } 171 172 uint_8 TOISegmented::MasterView::getFlag(int sn) { 173 return getView()->getFlag(sn); 174 } 175 176 void TOISegmented::MasterView::addToWaitList(BufferView* bv) { /* reader thread */ 177 // A view needs to wait for new data. 178 179 // There is a possible deadlock if no view can free old segments 180 // and we are waiting for write. 181 182 // we need to record "wont need before" for each view, and 183 // signal deadlock if any view that needs first segment data is sleeping 184 // while we are asleep 185 186 pthread_mutex_lock(&views_mutex); 187 waitingBuffers.insert(bv); 188 pthread_mutex_unlock(&views_mutex); 189 checkDeadLock(); 190 } 191 192 void TOISegmented::MasterView::removeFromWaitList(BufferView* bv) { /* reader thread */ 193 pthread_mutex_lock(&views_mutex); 194 waitingBuffers.erase(bv); 195 pthread_mutex_unlock(&views_mutex); 196 } 197 198 TOISegmented::BufferView* TOISegmented::MasterView::getView() { /* reader thread */ 199 BufferView* bv = (BufferView*) pthread_getspecific(buffer_key); 200 if (bv == NULL) { 201 bv = createView(); 202 pthread_setspecific(buffer_key, bv); 203 } 204 return bv; 205 }
Note:
See TracChangeset
for help on using the changeset viewer.