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

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

* empty log message *

File size: 3.5 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;
70
71 double* data;
72 uint_8* flags;
73 };
74
75 // Master view, gere le lock, et l'ecriture
76 class MasterView {
77 public:
78 MasterView(int bufsz=256, int maxseg=20);
79 ~MasterView();
80
81 void putData(int sn, double data, uint_8 flag);
82 void addToWaitList(BufferView* bv);
83
84 BufferView* getView(); // thread-specific
85
86 protected:
87 friend class BufferView;
88 void signalWaitingViews();
89 void nextSegment();
90 BufferView* createView();
91 void updateView(BufferView*); // called on reader thread of the view
92
93 BufferSegment* currentSegment;
94
95 int maxSegments;
96 int bufferSize;
97 int sn0; // First sn in first buffer
98 vector<BufferSegment*> segments; // Committed
99
100 pthread_mutex_t mutex; // lock for master buffer list access
101 pthread_cond_t condv; // waiting (read or write)
102
103 static const int NO_WAIT = 0;
104 static const int WAIT_READ = 1;
105 static const int WAIT_WRITE= 2;
106 int waitStatus;
107
108 set<BufferView*> waitingBuffers;
109 };
110
111
112 // per-thread read-only view of a buffer set
113 class BufferView {
114 public:
115 BufferView();
116 ~BufferView();
117
118 void sync(); // recupere les nouveaux segments, resync avec master
119 void wait(); // Passe en attente d'un nouveau segment
120 protected:
121 friend class MasterView;
122 MasterView* master;
123 vector<BufferSegment*> segments; // Committed
124 pthread_mutex_t mutex; // lock pour attente de segments
125 pthread_cond_t condv; // attente de segments
126 };
127
128
129
130};
131
132// Inline methods
133
134double TOISegmented::BufferSegment::getData(int sn) {
135 checkCommitted();
136 checkInRange(sn);
137 return data[sn-sn0];
138}
139
140uint_8 TOISegmented::BufferSegment::getFlag(int sn) {
141 checkCommitted();
142 checkInRange(sn);
143 return flags[sn-sn0];
144}
145
146#endif
Note: See TracBrowser for help on using the repository browser.