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

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

on rechange les include stl pour !&@@ SGI.

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