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

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

decorrelateur wiener

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