~ubuntu-branches/ubuntu/quantal/freewheeling/quantal

« back to all changes in this revision

Viewing changes to src/fweelin_mem.h

  • Committer: Bazaar Package Importer
  • Author(s): Paul Brossier
  • Date: 2005-08-06 15:11:54 UTC
  • Revision ID: james.westby@ubuntu.com-20050806151154-nvhhuxtyvgweh75u
Tags: upstream-0.5pre4
ImportĀ upstreamĀ versionĀ 0.5pre4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef __FWEELIN_MEM_H
 
2
#define __FWEELIN_MEM_H
 
3
 
 
4
class MemoryManager;
 
5
class Preallocated;
 
6
 
 
7
class PreallocatedType {
 
8
  friend class MemoryManager;
 
9
 
 
10
 public:
 
11
  // Default number of instances to keep preallocated
 
12
  const static int PREALLOC_DEFAULT_NUM_INSTANCES = 10;
 
13
 
 
14
  // Tells memory manager to start preallocating blocks of this type
 
15
  // Note for each type of preallocated data we can specify
 
16
  // a different number of instances to keep ready for RT consumption
 
17
  //
 
18
  // We must provide one instance of the Preallocated class as a reference
 
19
  // This is prealloc_base
 
20
  //
 
21
  // If block_mode is 1, an array of instances is used, and unused instances
 
22
  // are recycled instead of new ones constructed.
 
23
  PreallocatedType(MemoryManager *mmgr, Preallocated *prealloc_base,
 
24
                   int instance_size,
 
25
                   int prealloc_num_instances = 
 
26
                   PREALLOC_DEFAULT_NUM_INSTANCES,
 
27
                   char block_mode = 0);
 
28
  // Stops preallocating this type
 
29
  ~PreallocatedType();
 
30
 
 
31
  // Realtime-safe function to get a new instance of this class
 
32
  Preallocated *RTNew();
 
33
  // Realtime-safe function to delete this instance of this class
 
34
  void RTDelete(Preallocated *inst);
 
35
  
 
36
  // Perform any preallocations and pending deletes that are needed!
 
37
  // Called by memory manager
 
38
  void GoPreallocate();
 
39
  void GoPostdelete();
 
40
 
 
41
  // Cleanup- delete all preallocated instances of this type- called
 
42
  // on program exit
 
43
  void Cleanup();
 
44
 
 
45
  inline int GetBlockSize() { return prealloc_num_instances; };
 
46
  inline char GetBusy() { return busy; };
 
47
  
 
48
 private:
 
49
  
 
50
  char busy; // Busy flag- if we are playing with data structures 
 
51
             // the memory manager thread will wait
 
52
 
 
53
  // Actual size of one instance (we can't get it with RTTI, so you have to
 
54
  // pass it!)
 
55
  int instance_size;
 
56
 
 
57
  // Number of instances to keep preallocated
 
58
  int prealloc_num_instances;
 
59
 
 
60
  // Block mode or single instance mode?
 
61
  char block_mode;
 
62
  // Last block index scanned for free instances
 
63
  int block_last_idx;
 
64
 
 
65
  // List of free instances
 
66
  Preallocated *prealloc_free; 
 
67
  // List of instances in use
 
68
  Preallocated *prealloc_inuse;
 
69
 
 
70
  MemoryManager *mmgr;
 
71
  // MemoryManager maintains 2 lists of PreallocatedTypes
 
72
  PreallocatedType *next,
 
73
    *anext; // Next in active list
 
74
};
 
75
 
 
76
// This class is a base for classes that want to be preallocated
 
77
// and postdeleted-- classes in which new instances are needed
 
78
// in realtime-- the memory allocation is done in a nonrealtime thread
 
79
//
 
80
// One such allocate&delete thread exists for all preallocated types
 
81
// MemoryManager handles that thread. 
 
82
//
 
83
// Using this class as a base adds some bytes of size to each instance
 
84
// which might be a concern if you are allocating many instances!
 
85
class Preallocated {
 
86
  friend class PreallocatedType;
 
87
 
 
88
 public:
 
89
  // Default constructor calls recycle to init this instance
 
90
  Preallocated() : prealloc_mgr(0) {};
 
91
  virtual ~Preallocated() {};
 
92
 
 
93
  void *operator new(size_t s) {
 
94
    printf("ERROR: Preallocated type can not be allocated directly\n");
 
95
    exit(1);
 
96
  };
 
97
  void operator delete(void *d) {
 
98
    //printf("ERROR: Preallocated type can not be deleted directly\n");
 
99
    //exit(1);
 
100
 
 
101
    // We used to give an error message-
 
102
    // now we pass this delete on to RTDelete
 
103
    ((Preallocated *) d)->RTDelete();
 
104
  }
 
105
 
 
106
  // Realtime-safe function to get a new instance of this class
 
107
  Preallocated *RTNew() { 
 
108
    if (prealloc_mgr == 0) { // No mgr, so allocate nonRT way!
 
109
      //printf("WARNING: nonRT Prealloc in RTNew\n");
 
110
      return NewInstance();
 
111
    }
 
112
    else 
 
113
      return prealloc_mgr->RTNew();
 
114
  };
 
115
 
 
116
  // Realtime-safe function to delete this instance of this class
 
117
  void RTDelete() {
 
118
    if (prealloc_mgr == 0) { // No mgr, nonRT delete!
 
119
      //printf("WARNING: nonRT delete in RTDelete\n");
 
120
      ::delete this;
 
121
    }
 
122
    else 
 
123
      prealloc_mgr->RTDelete(this); 
 
124
  };
 
125
 
 
126
  // Returns the PreallocatedType manager associated with this type
 
127
  PreallocatedType *GetMgr() { return prealloc_mgr; };
 
128
 
 
129
  // Status values
 
130
  const static char PREALLOC_BASE_INSTANCE = 0, // Base instance, never deleted
 
131
    PREALLOC_PENDING_USE = 1,
 
132
    PREALLOC_IN_USE = 2,
 
133
    PREALLOC_PENDING_DELETE = 3;
 
134
 
 
135
  // This setup function is called from PreallocatedType
 
136
  // after a new instance of Preallocated is created.
 
137
  // It sets up the internal variables in this instance.
 
138
  void SetupPreallocated(PreallocatedType *mgr,
 
139
                         char status) {
 
140
    prealloc_mgr = mgr;
 
141
    prealloc_status = status;
 
142
    predata.prealloc_next = 0;
 
143
  };
 
144
 
 
145
 private:
 
146
 
 
147
  // Code to destroy a block of instances- only called in block mode
 
148
  // This is a workaround because operator delete[] is not virtual
 
149
  // and can not handle our arrays of derived instances
 
150
#define FWMEM_DEFINE_DELBLOCK  virtual void DelBlock() { ::delete[] this; };
 
151
  FWMEM_DEFINE_DELBLOCK;
 
152
  
 
153
  // Code to call new operator for the derived class (nonRT)
 
154
  // All allocation and lengthy initialization can be done here
 
155
  // If this type is allocated in block mode, NewInstance must allocate
 
156
  // not one instance, but an array of instances with prealloc_num_instances
 
157
  // size
 
158
  virtual Preallocated *NewInstance() = 0;
 
159
  
 
160
  // Code to recycle an old instance to be used again
 
161
  // This is called *only* in block mode when an instance is RTDeleted.
 
162
  // Instead of deleting and constructing instances, we recycle
 
163
  // instances and pass them as new instances.
 
164
  // 
 
165
  // So initialization code can go here, but this function
 
166
  // must be RT safe.
 
167
  virtual void Recycle() {};
 
168
 
 
169
  // Status of this instance
 
170
  char prealloc_status;
 
171
 
 
172
  // PreallocatedType that manages the allocation of new instances
 
173
  // ** With a table, this could be optimized out of each instance **
 
174
  PreallocatedType *prealloc_mgr;
 
175
 
 
176
  union {
 
177
    // In block mode,
 
178
    // Each instance is part of an array. And each array is part of a linked
 
179
    // list. So we have a list of blocks of instances. 
 
180
    // The 1st instance in a block points to the next block.
 
181
    // The 2nd instance in a block holds the # of free instances in that block:
 
182
    int prealloc_num_free;
 
183
 
 
184
    // Next instance- or in block mode, next block of instances
 
185
    Preallocated *prealloc_next;
 
186
  } predata;
 
187
};
 
188
 
 
189
class MemoryManager {
 
190
 public:
 
191
 
 
192
  MemoryManager();
 
193
  ~MemoryManager();
 
194
  
 
195
  // Starts managing the specified type
 
196
  void AddType(PreallocatedType *t);
 
197
  // Stops managing the specified type
 
198
  void DelType(PreallocatedType *t);
 
199
 
 
200
  // Wake up the manager thread- something to be done on the specified type
 
201
  void WakeUp(PreallocatedType *t);
 
202
 
 
203
 private:
 
204
 
 
205
  // Thread function
 
206
  static void *run_mgr_thread (void *ptr);
 
207
 
 
208
  // List of all PreallocatedTypes we are managing
 
209
  PreallocatedType *pts;
 
210
  // List of all PreallocatedTypes with activity pending
 
211
  PreallocatedType *apts;
 
212
 
 
213
  // Thread to preallocate and postdelete instances
 
214
  pthread_t mgr_thread;
 
215
  pthread_mutex_t mgr_thread_lock;
 
216
  pthread_cond_t  mgr_go;
 
217
  int threadgo;
 
218
};
 
219
 
 
220
#endif