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

Last change on this file since 1687 was 1686, checked in by aubourg, 24 years ago

* empty log message *

File size: 4.2 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:
20 TOISegmented();
21 TOISegmented(string nm);
22 ~TOISegmented();
23
24
25 protected:
[1671]26 class BufferSegment;
27 class BufferView;
28 class MasterView;
29
30
[1670]31 class BufferSegment {
32 public:
33 BufferSegment(int sz);
34 ~BufferSegment();
35 static const int NEW = 0;
[1671]36 static const int WRITE = 1; // single-thread write access
37 static const int COMMITTED = 2; // multiple read without lock are ok
[1670]38
39 int getStatus() {return status;}
[1671]40 void incRefCount();
41 void decRefCount();
42 int getRefCount();
43
[1670]44 void putData(int sn, double data, uint_8 flag);
45 inline double getData(int sn);
46 inline uint_8 getFlag(int sn);
[1671]47
48 bool isPastEnd(int sn) {
49 return sn >= sn+bufferSize;
50 }
[1670]51
52 private:
53 void checkCommitted() {
54 if (status != COMMITTED)
55 throw(ForbiddenError("TOISegment: Read on not committed buffer segment"));
56 }
57
58 void checkInRange(int sn) {
59 if (sn < sn0 || sn >= sn+bufferSize)
60 throw(RangeCheckError("TOISegment: out of range access in buffer segment"));
61 }
62
63
64 int status; // NEW, WRITE, COMMITTED
65 int bufferSize;
66 int sn0; // Samplenum du premier echantillon
67
68 int refcount; // Nombre de vues qui utilisent
[1686]69 pthread_mutex_t refcount_mutex; // Pour modification refcount
[1670]70
71 double* data;
72 uint_8* flags;
[1686]73
74 friend class BufferView;
75 friend class MasterView;
[1670]76 };
77
[1671]78 // Master view, gere le lock, et l'ecriture
[1670]79 class MasterView {
80 public:
[1671]81 MasterView(int bufsz=256, int maxseg=20);
[1670]82 ~MasterView();
83
[1671]84 void putData(int sn, double data, uint_8 flag);
[1686]85 double getData(int sn);
86 uint_8 getFlag(int sn);
87
88 protected:
[1671]89 void addToWaitList(BufferView* bv);
[1686]90 void removeFromWaitList(BufferView* bv);
[1671]91
92 BufferView* getView(); // thread-specific
93
94 friend class BufferView;
95 void signalWaitingViews();
96 void nextSegment();
97 BufferView* createView();
98 void updateView(BufferView*); // called on reader thread of the view
[1670]99
[1671]100 BufferSegment* currentSegment;
101
102 int maxSegments;
[1686]103 int segmentSize;
104 int sn0; // First sn in first segment
105 vector<BufferSegment*> segments; // Committed segments
[1671]106
[1686]107 pthread_mutex_t views_mutex; // lock for master buffer list access
108 pthread_mutex_t write_mutex; // for write waiting
109 pthread_cond_t condv; // waiting (read or write) (write only ?)
110 pthread_key_t buffer_key; // thread-specific buffer view
111 static void BufferDestroy(void *);
[1671]112
113 static const int NO_WAIT = 0;
114 static const int WAIT_READ = 1;
115 static const int WAIT_WRITE= 2;
116 int waitStatus;
117
118 set<BufferView*> waitingBuffers;
[1686]119
120 void checkDeadLock();
[1670]121 };
122
123
124 // per-thread read-only view of a buffer set
125 class BufferView {
126 public:
[1686]127 BufferView(MasterView*);
[1671]128 ~BufferView();
[1686]129
130 double getData(int sn);
131 uint_8 getFlag(int sn);
[1670]132
[1686]133 protected:
134 void wait(); // Passe en attente d'un nouveau segment -- lecture
[1671]135 void sync(); // recupere les nouveaux segments, resync avec master
[1686]136 void ensure(int sn);
137 void signal();
138
[1671]139 friend class MasterView;
140 MasterView* master;
141 vector<BufferSegment*> segments; // Committed
[1686]142 int sn0;
143 int segmentSize;
[1671]144 pthread_mutex_t mutex; // lock pour attente de segments
[1686]145 pthread_cond_t condv; // attente de segments (en lecture)
[1670]146 };
[1671]147
148
149
[1670]150};
151
[1686]152/***********************************/
153/* Inline methods -- BufferSegment */
154/***********************************/
[1670]155
156double TOISegmented::BufferSegment::getData(int sn) {
157 checkCommitted();
158 checkInRange(sn);
159 return data[sn-sn0];
160}
161
162uint_8 TOISegmented::BufferSegment::getFlag(int sn) {
163 checkCommitted();
164 checkInRange(sn);
165 return flags[sn-sn0];
166}
167
168#endif
Note: See TracBrowser for help on using the repository browser.