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

Last change on this file since 1742 was 1738, checked in by aubourg, 24 years ago

copyright

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