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

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

parallel mapmaking

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