source: Sophya/trunk/ArchTOIPipe/Kernel/toisegment.h@ 1690

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

segmentes

File size: 5.3 KB
Line 
1// This may look like C code, but it is really -*- C++ -*-
2#ifndef TOISEGMENT_H
3#define TOISEGMENT_H
4
5#include <vector>
6#include <set>
7
8#include "toi.h"
9
10// ------------ TOISegmented ------------------------------
11// Classe de TOI pour echantillonage regulier, avec buffer
12// segmente pour optimiser le multithread et limiter les
13// verrous.
14// Il faut que les fournisseurs fassent arriver les donnees
15// par samplenum croissant et continu.
16// --------------------------------------------------------
17
18class TOISegmented : public TOIRegular {
19 public:
20 TOISegmented(int bufsz=256, int maxseg=20);
21 TOISegmented(string nm, int bufsz=256, int maxseg=20);
22 ~TOISegmented();
23
24 virtual double getData(int i);
25 virtual void getData(int i, double& data, uint_8& flag);
26 virtual void putData(int i, double value, uint_8 flag=0);
27 virtual void wontNeedBefore(int i);
28 virtual void putDone();
29
30 // Methodes ignorees car on reimplemente les methodes de base
31 virtual DataStatus isDataAvail(int iStart, int iEnd);
32 virtual DataStatus isDataAvail(int i);
33 virtual DataStatus isDataAvailNL(int iStart, int iEnd); // abstract
34 virtual void waitForData(int iStart, int iEnd);
35 virtual void waitForData(int i);
36 virtual void waitForAnyData();
37 virtual int nextDataAvail(int iAfter); // abstract
38 virtual bool hasSomeData(); // abstract
39 virtual void doGetData(int i, double& data, uint_8& flag); // abs
40 virtual void doPutData(int i, double value, uint_8 flag=0); // abs
41
42
43 protected:
44 class BufferSegment;
45 class BufferView;
46 class MasterView;
47
48 MasterView* master;
49
50
51 class BufferSegment {
52 public:
53 BufferSegment(int sz);
54 ~BufferSegment();
55 static const int NEW = 0;
56 static const int WRITE = 1; // single-thread write access
57 static const int COMMITTED = 2; // multiple read without lock are ok
58
59 int getStatus() {return status;}
60 void incRefCount();
61 void decRefCount();
62 int getRefCount();
63
64 void putData(int sn, double data, uint_8 flag);
65 inline double getData(int sn);
66 inline uint_8 getFlag(int sn);
67
68 bool isPastEnd(int sn) {
69 return sn >= sn+bufferSize;
70 }
71
72 private:
73 void checkCommitted() {
74 if (status != COMMITTED)
75 throw(ForbiddenError("TOISegment: Read on not committed buffer segment"));
76 }
77
78 void checkInRange(int sn) {
79 if (sn < sn0 || sn >= sn+bufferSize)
80 throw(RangeCheckError("TOISegment: out of range access in buffer segment"));
81 }
82
83
84 int status; // NEW, WRITE, COMMITTED
85 int bufferSize;
86 int sn0; // Samplenum du premier echantillon
87
88 int refcount; // Nombre de vues qui utilisent
89 pthread_mutex_t refcount_mutex; // Pour modification refcount
90
91 double* data;
92 uint_8* flags;
93
94 friend class BufferView;
95 friend class MasterView;
96 };
97
98 // Master view, gere le lock, et l'ecriture
99 class MasterView {
100 public:
101 MasterView(int bufsz=256, int maxseg=20);
102 ~MasterView();
103
104 void putData(int sn, double data, uint_8 flag);
105 double getData(int sn);
106 uint_8 getFlag(int sn);
107 BufferView* getView(); // thread-specific
108 void putDone();
109
110 protected:
111 void addToWaitList(BufferView* bv);
112 void removeFromWaitList(BufferView* bv);
113
114
115 friend class BufferView;
116 void signalWaitingViews(); // views are waiting on read
117 void signal(); // we are waiting on write
118 void nextSegment();
119 void waitForCleaning();
120 BufferView* createView();
121 void updateView(BufferView*); // called on reader thread of the view
122
123 BufferSegment* currentSegment;
124
125 int maxSegments;
126 int segmentSize;
127 int sn0; // First sn in first segment
128 vector<BufferSegment*> segments; // Committed segments
129
130 pthread_mutex_t views_mutex; // lock for master buffer list access
131 pthread_mutex_t write_mutex; // for write waiting
132 pthread_cond_t condv; // waiting for cleaning (on writer thread)
133 pthread_key_t buffer_key; // thread-specific buffer view
134 static void BufferDestroy(void *);
135
136 bool waitingOnWrite; // wait on writer thread
137
138 set<BufferView*> waitingBuffers;
139 set<BufferView*> allViews;
140
141 void checkDeadLock();
142 };
143
144
145 // per-thread read-only view of a buffer set
146 class BufferView {
147 public:
148 BufferView(MasterView*);
149 ~BufferView();
150
151 double getData(int sn);
152 uint_8 getFlag(int sn);
153
154 void wontNeedBefore(int sn);
155
156 protected:
157 void wait(); // Passe en attente d'un nouveau segment -- lecture
158 void sync(); // recupere les nouveaux segments, resync avec master
159 void ensure(int sn);
160 void signal();
161
162 friend class MasterView;
163 MasterView* master;
164 vector<BufferSegment*> segments; // Committed
165 int sn0;
166 int segmentSize;
167 int firstNeeded;
168 pthread_mutex_t mutex; // lock pour attente de segments
169 pthread_cond_t condv; // attente de segments (en lecture)
170 };
171
172
173
174};
175
176/***********************************/
177/* Inline methods -- BufferSegment */
178/***********************************/
179
180double TOISegmented::BufferSegment::getData(int sn) {
181 checkCommitted();
182 checkInRange(sn);
183 return data[sn-sn0];
184}
185
186uint_8 TOISegmented::BufferSegment::getFlag(int sn) {
187 checkCommitted();
188 checkInRange(sn);
189 return flags[sn-sn0];
190}
191
192#endif
Note: See TracBrowser for help on using the repository browser.