Changeset 1686 in Sophya
- Timestamp:
- Oct 12, 2001, 1:17:10 AM (24 years ago)
- Location:
- trunk/ArchTOIPipe/Kernel
- Files:
-
- 2 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 } -
trunk/ArchTOIPipe/Kernel/toisegment.h
r1671 r1686 67 67 68 68 int refcount; // Nombre de vues qui utilisent 69 pthread_mutex_t refcount_mutex; 69 pthread_mutex_t refcount_mutex; // Pour modification refcount 70 70 71 71 double* data; 72 72 uint_8* flags; 73 74 friend class BufferView; 75 friend class MasterView; 73 76 }; 74 77 … … 80 83 81 84 void putData(int sn, double data, uint_8 flag); 85 double getData(int sn); 86 uint_8 getFlag(int sn); 87 88 protected: 82 89 void addToWaitList(BufferView* bv); 90 void removeFromWaitList(BufferView* bv); 83 91 84 92 BufferView* getView(); // thread-specific 85 93 86 protected:87 94 friend class BufferView; 88 95 void signalWaitingViews(); … … 94 101 95 102 int maxSegments; 96 int bufferSize;97 int sn0; // First sn in first buffer98 vector<BufferSegment*> segments; // Committed 103 int segmentSize; 104 int sn0; // First sn in first segment 105 vector<BufferSegment*> segments; // Committed segments 99 106 100 pthread_mutex_t mutex; // lock for master buffer list access 101 pthread_cond_t condv; // waiting (read or write) 107 pthread_mutex_t views_mutex; // lock for master buffer list access 108 pthread_mutex_t write_mutex; // for write waiting 109 pthread_cond_t condv; // waiting (read or write) (write only ?) 110 pthread_key_t buffer_key; // thread-specific buffer view 111 static void BufferDestroy(void *); 102 112 103 113 static const int NO_WAIT = 0; … … 107 117 108 118 set<BufferView*> waitingBuffers; 119 120 void checkDeadLock(); 109 121 }; 110 122 … … 113 125 class BufferView { 114 126 public: 115 BufferView( );127 BufferView(MasterView*); 116 128 ~BufferView(); 129 130 double getData(int sn); 131 uint_8 getFlag(int sn); 117 132 133 protected: 134 void wait(); // Passe en attente d'un nouveau segment -- lecture 118 135 void sync(); // recupere les nouveaux segments, resync avec master 119 void wait(); // Passe en attente d'un nouveau segment 120 protected: 136 void ensure(int sn); 137 void signal(); 138 121 139 friend class MasterView; 122 140 MasterView* master; 123 141 vector<BufferSegment*> segments; // Committed 142 int sn0; 143 int segmentSize; 124 144 pthread_mutex_t mutex; // lock pour attente de segments 125 pthread_cond_t condv; // attente de segments 145 pthread_cond_t condv; // attente de segments (en lecture) 126 146 }; 127 147 … … 130 150 }; 131 151 132 // Inline methods 152 /***********************************/ 153 /* Inline methods -- BufferSegment */ 154 /***********************************/ 133 155 134 156 double TOISegmented::BufferSegment::getData(int sn) {
Note:
See TracChangeset
for help on using the changeset viewer.