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

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

* empty log message *

File size: 4.2 KB
Line 
1// This may look like C code, but it is really -*- C++ -*-
2#ifndef TOISEGMENT_H
3#define TOISEGMENT_H
4
5#include <vector>
6#include <set>
7
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:
26 class BufferSegment;
27 class BufferView;
28 class MasterView;
29
30
31 class BufferSegment {
32 public:
33 BufferSegment(int sz);
34 ~BufferSegment();
35 static const int NEW = 0;
36 static const int WRITE = 1; // single-thread write access
37 static const int COMMITTED = 2; // multiple read without lock are ok
38
39 int getStatus() {return status;}
40 void incRefCount();
41 void decRefCount();
42 int getRefCount();
43
44 void putData(int sn, double data, uint_8 flag);
45 inline double getData(int sn);
46 inline uint_8 getFlag(int sn);
47
48 bool isPastEnd(int sn) {
49 return sn >= sn+bufferSize;
50 }
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
69 pthread_mutex_t refcount_mutex; // Pour modification refcount
70
71 double* data;
72 uint_8* flags;
73
74 friend class BufferView;
75 friend class MasterView;
76 };
77
78 // Master view, gere le lock, et l'ecriture
79 class MasterView {
80 public:
81 MasterView(int bufsz=256, int maxseg=20);
82 ~MasterView();
83
84 void putData(int sn, double data, uint_8 flag);
85 double getData(int sn);
86 uint_8 getFlag(int sn);
87
88 protected:
89 void addToWaitList(BufferView* bv);
90 void removeFromWaitList(BufferView* bv);
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
99
100 BufferSegment* currentSegment;
101
102 int maxSegments;
103 int segmentSize;
104 int sn0; // First sn in first segment
105 vector<BufferSegment*> segments; // Committed segments
106
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 *);
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;
119
120 void checkDeadLock();
121 };
122
123
124 // per-thread read-only view of a buffer set
125 class BufferView {
126 public:
127 BufferView(MasterView*);
128 ~BufferView();
129
130 double getData(int sn);
131 uint_8 getFlag(int sn);
132
133 protected:
134 void wait(); // Passe en attente d'un nouveau segment -- lecture
135 void sync(); // recupere les nouveaux segments, resync avec master
136 void ensure(int sn);
137 void signal();
138
139 friend class MasterView;
140 MasterView* master;
141 vector<BufferSegment*> segments; // Committed
142 int sn0;
143 int segmentSize;
144 pthread_mutex_t mutex; // lock pour attente de segments
145 pthread_cond_t condv; // attente de segments (en lecture)
146 };
147
148
149
150};
151
152/***********************************/
153/* Inline methods -- BufferSegment */
154/***********************************/
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.