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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [services/] [memalloc/] [common/] [current/] [include/] [mempoolt.inl] - Blame information for rev 838

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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