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

Last change on this file since 2454 was 2454, checked in by aubourg, 22 years ago

pb longs sur magique

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