OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [ecos-2.0/] [packages/] [services/] [memalloc/] [common/] [v2_0/] [include/] [mempoolt.inl] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1254 phoenix
#ifndef CYGONCE_KERNEL_MEMPOOLT_INL
2
#define CYGONCE_KERNEL_MEMPOOLT_INL
3
 
4
//==========================================================================
5
//
6
//      mempoolt.inl
7
//
8
//      Mempoolt (Memory pool template) class declarations
9
//
10
//==========================================================================
11
//####ECOSGPLCOPYRIGHTBEGIN####
12
// -------------------------------------------
13
// This file is part of eCos, the Embedded Configurable Operating System.
14
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
15
//
16
// eCos is free software; you can redistribute it and/or modify it under
17
// the terms of the GNU General Public License as published by the Free
18
// Software Foundation; either version 2 or (at your option) any later version.
19
//
20
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
21
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
22
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
23
// for more details.
24
//
25
// You should have received a copy of the GNU General Public License along
26
// with eCos; if not, write to the Free Software Foundation, Inc.,
27
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
28
//
29
// As a special exception, if other files instantiate templates or use macros
30
// or inline functions from this file, or you compile this file and link it
31
// with other works to produce a work based on this file, this file does not
32
// by itself cause the resulting work to be covered by the GNU General Public
33
// License. However the source code for this file must still be made available
34
// in accordance with section (3) of the GNU General Public License.
35
//
36
// This exception does not invalidate any other reasons why a work based on
37
// this file might be covered by the GNU General Public License.
38
//
39
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
40
// at http://sources.redhat.com/ecos/ecos-license/
41
// -------------------------------------------
42
//####ECOSGPLCOPYRIGHTEND####
43
//==========================================================================
44
//#####DESCRIPTIONBEGIN####
45
//
46
// Author(s):   hmt
47
// Contributors:        hmt
48
// Date:        1998-02-10
49
// Purpose:     Define Mempoolt class interface
50
 
51
// Description: The class defined here provides the APIs for thread-safe,
52
//              kernel-savvy memory managers; make a class with the
53
//              underlying allocator as the template parameter.
54
// Usage:       #include 
55
//
56
//
57
//####DESCRIPTIONEND####
58
//
59
//==========================================================================
60
 
61
#include   // implementation eg. Cyg_Thread::self();
62
#include    // implementation eg. Cyg_Scheduler::lock();
63
 
64
// -------------------------------------------------------------------------
65
// Constructor; we _require_ these arguments and just pass them through to
66
// the implementation memory pool in use.
67
template 
68
Cyg_Mempoolt::Cyg_Mempoolt(
69
    cyg_uint8 *base,
70
    cyg_int32 size,
71
    CYG_ADDRWORD arg_thru)              // Constructor
72
    : pool( base, size, arg_thru )
73
{
74
}
75
 
76
 
77
template 
78
Cyg_Mempoolt::~Cyg_Mempoolt()  // destructor
79
{
80
    // Prevent preemption
81
    Cyg_Scheduler::lock();
82
 
83
    while ( ! queue.empty() ) {
84
        Cyg_Thread *thread = queue.dequeue();
85
        thread->set_wake_reason( Cyg_Thread::DESTRUCT );
86
        thread->wake();
87
    }
88
 
89
    // Unlock the scheduler and maybe switch threads
90
    Cyg_Scheduler::unlock();
91
}
92
 
93
// -------------------------------------------------------------------------
94
// get some memory; wait if none available
95
template 
96
inline cyg_uint8 *
97
Cyg_Mempoolt::alloc( cyg_int32 size )
98
{
99
    CYG_REPORT_FUNCTION();
100
 
101
    Cyg_Thread *self = Cyg_Thread::self();
102
 
103
    // Prevent preemption
104
    Cyg_Scheduler::lock();
105
    CYG_ASSERTCLASS( this, "Bad this pointer");
106
 
107
    // Loop while we got no memory, sleeping each time around the
108
    // loop. This copes with the possibility of a higher priority thread
109
    // grabbing the freed storage between the wakeup in free() and this
110
    // thread actually starting.
111
    cyg_uint8 *ret;
112
    cyg_bool result = true;
113
    while( result && (NULL == (ret = pool.alloc( size ))) ) {
114
        self->set_sleep_reason( Cyg_Thread::WAIT );
115
        self->sleep();
116
        queue.enqueue( self );
117
 
118
        CYG_ASSERT( 1 == Cyg_Scheduler::get_sched_lock(),
119
                    "Called with non-zero scheduler lock");
120
 
121
        // Unlock scheduler and allow other threads to run
122
        Cyg_Scheduler::unlock();
123
        Cyg_Scheduler::lock();
124
 
125
        CYG_ASSERTCLASS( this, "Bad this pointer");
126
 
127
        switch( self->get_wake_reason() )
128
        {
129
        case Cyg_Thread::DESTRUCT:
130
        case Cyg_Thread::BREAK:
131
            result = false;
132
            break;
133
 
134
        case Cyg_Thread::EXIT:
135
            self->exit();
136
            break;
137
 
138
        default:
139
            break;
140
        }
141
    }
142
    CYG_ASSERTCLASS( this, "Bad this pointer");
143
 
144
    if ( ! result )
145
        ret = NULL;
146
 
147
    // Unlock the scheduler and maybe switch threads
148
    Cyg_Scheduler::unlock();
149
    CYG_REPORT_RETVAL( ret );
150
    return ret;
151
}
152
 
153
#ifdef CYGFUN_KERNEL_THREADS_TIMER
154
// -------------------------------------------------------------------------
155
// get some memory with a timeout
156
template 
157
inline cyg_uint8 *
158
Cyg_Mempoolt::alloc( cyg_int32 size, cyg_tick_count abs_timeout )
159
{
160
    CYG_REPORT_FUNCTION();
161
 
162
    Cyg_Thread *self = Cyg_Thread::self();
163
 
164
    // Prevent preemption
165
    Cyg_Scheduler::lock();
166
    CYG_ASSERTCLASS( this, "Bad this pointer");
167
 
168
    // Loop while we got no memory, sleeping each time around the
169
    // loop. This copes with the possibility of a higher priority thread
170
    // grabbing the freed storage between the wakeup in free() and this
171
    // thread actually starting.
172
    cyg_uint8 *ret;
173
    cyg_bool result = true;
174
    // Set the timer _once_ outside the loop.
175
    self->set_timer( abs_timeout, Cyg_Thread::TIMEOUT );
176
 
177
    // If the timeout is in the past, the wake reason will have been
178
    // set to something other than NONE already. Set the result false
179
    // to force an immediate return.
180
 
181
    if( self->get_wake_reason() != Cyg_Thread::NONE )
182
        result = false;
183
 
184
    while( result && (NULL == (ret = pool.alloc( size ))) ) {
185
        self->set_sleep_reason( Cyg_Thread::TIMEOUT );
186
        self->sleep();
187
        queue.enqueue( self );
188
 
189
        CYG_ASSERT( 1 == Cyg_Scheduler::get_sched_lock(),
190
                    "Called with non-zero scheduler lock");
191
 
192
        // Unlock scheduler and allow other threads to run
193
        Cyg_Scheduler::unlock();
194
        Cyg_Scheduler::lock();
195
 
196
        CYG_ASSERTCLASS( this, "Bad this pointer");
197
        switch( self->get_wake_reason() )
198
        {
199
        case Cyg_Thread::TIMEOUT:
200
            result = false;
201
            break;
202
 
203
        case Cyg_Thread::DESTRUCT:
204
        case Cyg_Thread::BREAK:
205
            result = false;
206
            break;
207
 
208
        case Cyg_Thread::EXIT:
209
            self->exit();
210
            break;
211
 
212
        default:
213
            break;
214
        }
215
    }
216
 
217
    CYG_ASSERTCLASS( this, "Bad this pointer");
218
 
219
    if ( ! result )
220
        ret = NULL;
221
 
222
    // clear the timer; if it actually fired, no worries.
223
    self->clear_timer();
224
 
225
    // Unlock the scheduler and maybe switch threads
226
    Cyg_Scheduler::unlock();
227
    CYG_REPORT_RETVAL( ret );
228
    return ret;
229
}
230
#endif
231
 
232
// -------------------------------------------------------------------------
233
// get some memory, return NULL if none available
234
template 
235
inline cyg_uint8 *
236
Cyg_Mempoolt::try_alloc( cyg_int32 size )
237
{
238
    CYG_REPORT_FUNCTION();
239
 
240
    // Prevent preemption
241
    Cyg_Scheduler::lock();
242
    CYG_ASSERTCLASS( this, "Bad this pointer");
243
 
244
    cyg_uint8 *ret = pool.alloc( size );
245
 
246
    CYG_ASSERTCLASS( this, "Bad this pointer");
247
 
248
    // Unlock the scheduler and maybe switch threads
249
    Cyg_Scheduler::unlock();
250
    CYG_REPORT_RETVAL( ret );
251
    return ret;
252
}
253
 
254
 
255
// -------------------------------------------------------------------------
256
// free the memory back to the pool
257
template 
258
cyg_bool
259
Cyg_Mempoolt::free( cyg_uint8 *p, cyg_int32 size )
260
{
261
    // Prevent preemption
262
    Cyg_Scheduler::lock();
263
    CYG_ASSERTCLASS( this, "Bad this pointer");
264
 
265
    cyg_int32 ret = pool.free( p, size );
266
 
267
    CYG_ASSERTCLASS( this, "Bad this pointer");
268
 
269
    while ( ret && !queue.empty() ) {
270
        // we succeeded and there are people waiting
271
        Cyg_Thread *thread = queue.dequeue();
272
 
273
        CYG_ASSERTCLASS( thread, "Bad thread pointer");
274
 
275
        // we wake them all up (ie. broadcast) to cope with variable block
276
        // allocators freeing a big block when lots of small allocs wait.
277
        thread->set_wake_reason( Cyg_Thread::DONE );
278
        thread->wake();
279
        // we cannot yield here; if a higher prio thread can't satisfy its
280
        // request it would re-queue and we would loop forever
281
    }
282
    // Unlock the scheduler and maybe switch threads
283
    Cyg_Scheduler::unlock();
284
    return ret;
285
}
286
 
287
// -------------------------------------------------------------------------
288
// if applicable: return -1 if not fixed size
289
template 
290
inline cyg_int32
291
Cyg_Mempoolt::get_blocksize()
292
{
293
    // there should not be any atomicity issues here
294
    return pool.get_blocksize();
295
}
296
 
297
// -------------------------------------------------------------------------
298
// these two are obvious and generic, but need atomicity protection (maybe)
299
template 
300
inline cyg_int32
301
Cyg_Mempoolt::get_totalmem()
302
{
303
    // Prevent preemption
304
    Cyg_Scheduler::lock();
305
    CYG_ASSERTCLASS( this, "Bad this pointer");
306
 
307
    cyg_int32 ret = pool.get_totalmem();
308
 
309
    // Unlock the scheduler and maybe switch threads
310
    Cyg_Scheduler::unlock();
311
    return ret;
312
}
313
 
314
template 
315
inline cyg_int32
316
Cyg_Mempoolt::get_freemem()
317
{
318
    // Prevent preemption
319
    Cyg_Scheduler::lock();
320
    CYG_ASSERTCLASS( this, "Bad this pointer");
321
 
322
    cyg_int32 ret = pool.get_freemem();
323
 
324
    // Unlock the scheduler and maybe switch threads
325
    Cyg_Scheduler::unlock();
326
    return ret;
327
}
328
 
329
// -------------------------------------------------------------------------
330
// get information about the construction parameters for external
331
// freeing after the destruction of the holding object
332
template 
333
inline void
334
Cyg_Mempoolt::get_arena(
335
    cyg_uint8 * &base, cyg_int32 &size, CYG_ADDRWORD &arg_thru )
336
{
337
    // Prevent preemption
338
    Cyg_Scheduler::lock();
339
    CYG_ASSERTCLASS( this, "Bad this pointer");
340
 
341
    pool.get_arena( base, size, arg_thru );
342
 
343
    // Unlock the scheduler and maybe switch threads
344
    Cyg_Scheduler::unlock();
345
}
346
 
347
// -------------------------------------------------------------------------
348
// Return the size of the memory allocation (previously returned
349
// by alloc() or try_alloc() ) at ptr. Returns -1 if not found
350
template 
351
cyg_int32
352
Cyg_Mempoolt::get_allocation_size( cyg_uint8 *ptr )
353
{
354
    cyg_int32 ret;
355
 
356
    // Prevent preemption
357
    Cyg_Scheduler::lock();
358
    CYG_ASSERTCLASS( this, "Bad this pointer");
359
 
360
    ret = pool.get_allocation_size( ptr );
361
 
362
    // Unlock the scheduler and maybe switch threads
363
    Cyg_Scheduler::unlock();
364
 
365
    return ret;
366
}
367
 
368
// -------------------------------------------------------------------------
369
// debugging/assert function
370
 
371
#ifdef CYGDBG_USE_ASSERTS
372
 
373
template 
374
inline cyg_bool
375
Cyg_Mempoolt::check_this(cyg_assert_class_zeal zeal) const
376
{
377
    CYG_REPORT_FUNCTION();
378
 
379
    if ( Cyg_Thread::DESTRUCT == Cyg_Thread::self()->get_wake_reason() )
380
        // then the whole thing is invalid, and we know it.
381
        // so return OK, since this check should NOT make an error.
382
        return true;
383
 
384
    // check that we have a non-NULL pointer first
385
    if( this == NULL ) return false;
386
 
387
    return true;
388
}
389
#endif
390
 
391
// -------------------------------------------------------------------------
392
#endif // ifndef CYGONCE_KERNEL_MEMPOOLT_INL
393
// EOF mempoolt.inl

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.