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

Last change on this file since 1747 was 1743, checked in by aubourg, 24 years ago

optim lecture/ecriture en bloc

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