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

Last change on this file since 1755 was 1754, checked in by aubourg, 24 years ago

iostream pour magique...

File size: 6.1 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
[1754]7// $Id: toisegment.h,v 1.12 2001-11-13 15:08:54 aubourg Exp $
[1738]8
[1670]9#ifndef TOISEGMENT_H
10#define TOISEGMENT_H
11
[1671]12#include <vector>
13#include <set>
14
[1670]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:
[1689]27 TOISegmented(int bufsz=256, int maxseg=20);
28 TOISegmented(string nm, int bufsz=256, int maxseg=20);
[1699]29 TOISegmented(char* cnm, int bufsz=256, int maxseg=20);
[1670]30 ~TOISegmented();
31
[1689]32 virtual double getData(int i);
33 virtual void getData(int i, double& data, uint_8& flag);
[1743]34 virtual void getData(int i, int n, double* data, uint_8* flg=0);
[1689]35 virtual void putData(int i, double value, uint_8 flag=0);
[1743]36 virtual void putData(int i, int n, double const* val, uint_8 const* flg=0);
[1689]37 virtual void wontNeedBefore(int i);
38 virtual void putDone();
[1692]39 virtual void addConsumer(TOIProcessor*);
[1689]40
[1690]41 // Methodes ignorees car on reimplemente les methodes de base
[1689]42 virtual DataStatus isDataAvail(int iStart, int iEnd);
43 virtual DataStatus isDataAvail(int i);
[1754]44 virtual DataStatus isDataAvailNL(int i);
[1689]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
[1670]54
55 protected:
[1671]56 class BufferSegment;
57 class BufferView;
58 class MasterView;
59
[1689]60 MasterView* master;
[1671]61
[1689]62
[1670]63 class BufferSegment {
64 public:
65 BufferSegment(int sz);
66 ~BufferSegment();
67 static const int NEW = 0;
[1671]68 static const int WRITE = 1; // single-thread write access
69 static const int COMMITTED = 2; // multiple read without lock are ok
[1670]70
71 int getStatus() {return status;}
[1671]72 void incRefCount();
73 void decRefCount();
74 int getRefCount();
75
[1670]76 void putData(int sn, double data, uint_8 flag);
[1743]77 void putData(int sn, int n, double const* data, uint_8 const* flag);
[1670]78 inline double getData(int sn);
79 inline uint_8 getFlag(int sn);
[1743]80 void getData(int sn, int n, double* data, uint_8* flag);
[1671]81
82 bool isPastEnd(int sn) {
83 return sn >= sn+bufferSize;
84 }
[1670]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
[1686]103 pthread_mutex_t refcount_mutex; // Pour modification refcount
[1670]104
105 double* data;
106 uint_8* flags;
[1686]107
108 friend class BufferView;
109 friend class MasterView;
[1670]110 };
111
[1671]112 // Master view, gere le lock, et l'ecriture
[1670]113 class MasterView {
114 public:
[1710]115 MasterView(int bufsz=256, int maxseg=20, string nm="");
[1670]116 ~MasterView();
117
[1671]118 void putData(int sn, double data, uint_8 flag);
[1686]119 double getData(int sn);
120 uint_8 getFlag(int sn);
[1743]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);
[1689]123 BufferView* getView(); // thread-specific
124 void putDone();
[1686]125
126 protected:
[1671]127
128 friend class BufferView;
[1692]129 friend class TOISegmented;
[1710]130 string name;
[1689]131 void signalWaitingViews(); // views are waiting on read
[1692]132 void signalWrite(); // we are waiting on write
[1671]133 void nextSegment();
[1689]134 void waitForCleaning();
[1671]135 BufferView* createView();
136 void updateView(BufferView*); // called on reader thread of the view
[1670]137
[1671]138 BufferSegment* currentSegment;
139
140 int maxSegments;
[1686]141 int segmentSize;
142 int sn0; // First sn in first segment
143 vector<BufferSegment*> segments; // Committed segments
[1692]144 int nConsumers;
[1671]145
[1686]146 pthread_mutex_t views_mutex; // lock for master buffer list access
[1692]147 pthread_cond_t write_wait_condv; // waiting for cleaning (on writer thread)
[1686]148 pthread_key_t buffer_key; // thread-specific buffer view
149 static void BufferDestroy(void *);
[1671]150
[1692]151 pthread_mutex_t read_wait_mutex;
152 pthread_cond_t read_wait_condv;
153
[1689]154 bool waitingOnWrite; // wait on writer thread
[1711]155 int waitingViews;
[1671]156
[1690]157 set<BufferView*> allViews;
[1686]158
159 void checkDeadLock();
[1670]160 };
161
162
163 // per-thread read-only view of a buffer set
164 class BufferView {
165 public:
[1686]166 BufferView(MasterView*);
[1671]167 ~BufferView();
[1686]168
169 double getData(int sn);
170 uint_8 getFlag(int sn);
[1743]171 void getData(int i, int n, double* data, uint_8* flg);
[1689]172
173 void wontNeedBefore(int sn);
[1670]174
[1686]175 protected:
176 void wait(); // Passe en attente d'un nouveau segment -- lecture
[1671]177 void sync(); // recupere les nouveaux segments, resync avec master
[1686]178 void ensure(int sn);
179
[1692]180 bool waiting;
181
[1671]182 friend class MasterView;
183 MasterView* master;
184 vector<BufferSegment*> segments; // Committed
[1686]185 int sn0;
186 int segmentSize;
[1689]187 int firstNeeded;
[1670]188 };
[1671]189
190
191
[1670]192};
193
[1686]194/***********************************/
195/* Inline methods -- BufferSegment */
196/***********************************/
[1670]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.