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

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

bugs de synchro corriges

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