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

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

thread debugging

File size: 5.2 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 virtual void addConsumer(TOIProcessor*);
30
31 // Methodes ignorees car on reimplemente les methodes de base
32 virtual DataStatus isDataAvail(int iStart, int iEnd);
33 virtual DataStatus isDataAvail(int i);
34 virtual DataStatus isDataAvailNL(int iStart, int iEnd); // abstract
35 virtual void waitForData(int iStart, int iEnd);
36 virtual void waitForData(int i);
37 virtual void waitForAnyData();
38 virtual int nextDataAvail(int iAfter); // abstract
39 virtual bool hasSomeData(); // abstract
40 virtual void doGetData(int i, double& data, uint_8& flag); // abs
41 virtual void doPutData(int i, double value, uint_8 flag=0); // abs
42
43
44 protected:
45 class BufferSegment;
46 class BufferView;
47 class MasterView;
48
49 MasterView* master;
50
51
52 class BufferSegment {
53 public:
54 BufferSegment(int sz);
55 ~BufferSegment();
56 static const int NEW = 0;
57 static const int WRITE = 1; // single-thread write access
58 static const int COMMITTED = 2; // multiple read without lock are ok
59
60 int getStatus() {return status;}
61 void incRefCount();
62 void decRefCount();
63 int getRefCount();
64
65 void putData(int sn, double data, uint_8 flag);
66 inline double getData(int sn);
67 inline uint_8 getFlag(int sn);
68
69 bool isPastEnd(int sn) {
70 return sn >= sn+bufferSize;
71 }
72
73 private:
74 void checkCommitted() {
75 if (status != COMMITTED)
76 throw(ForbiddenError("TOISegment: Read on not committed buffer segment"));
77 }
78
79 void checkInRange(int sn) {
80 if (sn < sn0 || sn >= sn+bufferSize)
81 throw(RangeCheckError("TOISegment: out of range access in buffer segment"));
82 }
83
84
85 int status; // NEW, WRITE, COMMITTED
86 int bufferSize;
87 int sn0; // Samplenum du premier echantillon
88
89 int refcount; // Nombre de vues qui utilisent
90 pthread_mutex_t refcount_mutex; // Pour modification refcount
91
92 double* data;
93 uint_8* flags;
94
95 friend class BufferView;
96 friend class MasterView;
97 };
98
99 // Master view, gere le lock, et l'ecriture
100 class MasterView {
101 public:
102 MasterView(int bufsz=256, int maxseg=20);
103 ~MasterView();
104
105 void putData(int sn, double data, uint_8 flag);
106 double getData(int sn);
107 uint_8 getFlag(int sn);
108 BufferView* getView(); // thread-specific
109 void putDone();
110
111 protected:
112
113 friend class BufferView;
114 friend class TOISegmented;
115 void signalWaitingViews(); // views are waiting on read
116 void signalWrite(); // we are waiting on write
117 void nextSegment();
118 void waitForCleaning();
119 BufferView* createView();
120 void updateView(BufferView*); // called on reader thread of the view
121
122 BufferSegment* currentSegment;
123
124 int maxSegments;
125 int segmentSize;
126 int sn0; // First sn in first segment
127 vector<BufferSegment*> segments; // Committed segments
128 int nConsumers;
129
130 pthread_mutex_t views_mutex; // lock for master buffer list access
131 pthread_cond_t write_wait_condv; // waiting for cleaning (on writer thread)
132 pthread_key_t buffer_key; // thread-specific buffer view
133 static void BufferDestroy(void *);
134
135 pthread_mutex_t read_wait_mutex;
136 pthread_cond_t read_wait_condv;
137
138 bool waitingOnWrite; // wait on writer thread
139
140 set<BufferView*> allViews;
141
142 void checkDeadLock();
143 };
144
145
146 // per-thread read-only view of a buffer set
147 class BufferView {
148 public:
149 BufferView(MasterView*);
150 ~BufferView();
151
152 double getData(int sn);
153 uint_8 getFlag(int sn);
154
155 void wontNeedBefore(int sn);
156
157 protected:
158 void wait(); // Passe en attente d'un nouveau segment -- lecture
159 void sync(); // recupere les nouveaux segments, resync avec master
160 void ensure(int sn);
161
162 bool waiting;
163
164 friend class MasterView;
165 MasterView* master;
166 vector<BufferSegment*> segments; // Committed
167 int sn0;
168 int segmentSize;
169 int firstNeeded;
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.