annotate packages/services/memalloc/common/current/include/mvarimpl.inl @ 159:511f4dc167f6

Merge from eCos master repository on 2001-05-18-01:30:05-BST
author jlarmour
date Fri, 18 May 2001 06:32:28 +0000
parents 6ed91473a1cd
children 0d2b193a635f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1 #ifndef CYGONCE_MEMALLOC_MVARIMPL_INL
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2 #define CYGONCE_MEMALLOC_MVARIMPL_INL
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
4 //==========================================================================
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
5 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
6 // mvarimpl.inl
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
7 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
8 // Memory pool with variable block class declarations
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
9 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
10 //==========================================================================
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
11 //####COPYRIGHTBEGIN####
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
12 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
13 // -------------------------------------------
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
14 // The contents of this file are subject to the Red Hat eCos Public License
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
15 // Version 1.1 (the "License"); you may not use this file except in
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
16 // compliance with the License. You may obtain a copy of the License at
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
17 // http://www.redhat.com/
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
18 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
19 // Software distributed under the License is distributed on an "AS IS"
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
20 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
21 // License for the specific language governing rights and limitations under
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
22 // the License.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
23 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
24 // The Original Code is eCos - Embedded Configurable Operating System,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
25 // released September 30, 1998.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
26 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
27 // The Initial Developer of the Original Code is Red Hat.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
28 // Portions created by Red Hat are
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
29 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
30 // All Rights Reserved.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
31 // -------------------------------------------
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
32 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
33 //####COPYRIGHTEND####
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
34 //==========================================================================
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
35 //#####DESCRIPTIONBEGIN####
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
36 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
37 // Author(s): hmt
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
38 // Contributors: jlarmour
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
39 // Date: 2000-06-12
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
40 // Purpose: Define Mvarimpl class interface
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
41 // Description: Inline class for constructing a variable block allocator
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
42 // Usage: #include <cyg/memalloc/mvarimpl.hxx>
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
43 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
44 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
45 //####DESCRIPTIONEND####
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
46 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
47 //==========================================================================
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
48
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
49 #include <pkgconf/memalloc.h>
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
50 #include <cyg/memalloc/mvarimpl.hxx>
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
51
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
52 #include <cyg/infra/cyg_ass.h> // assertion support
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
53 #include <cyg/infra/cyg_trac.h> // tracing support
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
54
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
55 // Simple allocator
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
56
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
57 // The free list is stored on a doubly linked list, each member of
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
58 // which is stored in the body of the free memory. The head of the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
59 // list has the same structure but its size field is zero. This
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
60 // resides in the memory pool structure. Always having at least one
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
61 // item on the list simplifies the alloc and free code.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
62
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
63 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
64 inline cyg_int32
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
65 Cyg_Mempool_Variable_Implementation::roundup( cyg_int32 size )
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
66 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
67
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
68 size += sizeof(struct memdq);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
69 size = (size + alignment - 1) & -alignment;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
70 return size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
71 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
72
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
73 inline struct Cyg_Mempool_Variable_Implementation::memdq *
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
74 Cyg_Mempool_Variable_Implementation::addr2memdq( cyg_uint8 *addr )
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
75 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
76 struct memdq *dq;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
77 dq = (struct memdq *)(roundup((cyg_int32)addr) - sizeof(struct memdq));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
78 return dq;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
79 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
80
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
81 inline struct Cyg_Mempool_Variable_Implementation::memdq *
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
82 Cyg_Mempool_Variable_Implementation::alloc2memdq( cyg_uint8 *addr )
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
83 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
84 return (struct memdq *)(addr - sizeof(struct memdq));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
85 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
86
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
87 inline cyg_uint8 *
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
88 Cyg_Mempool_Variable_Implementation::memdq2alloc( struct memdq *dq )
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
89 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
90 return ((cyg_uint8 *)dq + sizeof(struct memdq));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
91 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
92
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
93 // -------------------------------------------------------------------------
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
94
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
95 inline void
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
96 Cyg_Mempool_Variable_Implementation::insert_free_block( struct memdq *dq )
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
97 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
98 struct memdq *hdq=&head;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
99
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
100 freemem += dq->size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
101 #ifdef CYGSEM_MEMALLOC_ALLOCATOR_VARIABLE_COALESCE
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
102 // For simple coalescing have the free list be sorted by memory base address
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
103 struct memdq *idq;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
104
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
105 for (idq = hdq->next; idq != hdq; idq = idq->next) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
106 if (idq > dq)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
107 break;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
108 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
109 // we want to insert immediately before idq
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
110 dq->next = idq;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
111 dq->prev = idq->prev;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
112 idq->prev = dq;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
113 dq->prev->next = dq;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
114
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
115 // Now do coalescing, but leave the head of the list alone.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
116 if (dq->next != hdq && (char *)dq + dq->size == (char *)dq->next) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
117 dq->size += dq->next->size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
118 dq->next = dq->next->next;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
119 dq->next->prev = dq;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
120 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
121 if (dq->prev != hdq && (char *)dq->prev + dq->prev->size == (char *)dq) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
122 dq->prev->size += dq->size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
123 dq->prev->next = dq->next;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
124 dq->next->prev = dq->prev;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
125 dq = dq->prev;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
126 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
127 #else
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
128 dq->prev = hdq;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
129 dq->next = hdq->next;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
130 hdq->next = dq;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
131 dq->next->prev=dq;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
132 #endif
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
133 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
134
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
135 // -------------------------------------------------------------------------
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
136
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
137 inline
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
138 Cyg_Mempool_Variable_Implementation::Cyg_Mempool_Variable_Implementation(
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
139 cyg_uint8 *base,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
140 cyg_int32 size,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
141 CYG_ADDRWORD align )
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
142 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
143 CYG_REPORT_FUNCTION();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
144
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
145 CYG_ASSERT( align > 0, "Bad alignment" );
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
146 CYG_ASSERT(0!=align ,"align is zero");
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
147 CYG_ASSERT(0==(align & align-1),"align not a power of 2");
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
148
159
511f4dc167f6 Merge from eCos master repository on 2001-05-18-01:30:05-BST
jlarmour
parents: 115
diff changeset
149 if ((unsigned)size < sizeof(struct memdq)) {
511f4dc167f6 Merge from eCos master repository on 2001-05-18-01:30:05-BST
jlarmour
parents: 115
diff changeset
150 bottom = NULL;
511f4dc167f6 Merge from eCos master repository on 2001-05-18-01:30:05-BST
jlarmour
parents: 115
diff changeset
151 return;
511f4dc167f6 Merge from eCos master repository on 2001-05-18-01:30:05-BST
jlarmour
parents: 115
diff changeset
152 }
511f4dc167f6 Merge from eCos master repository on 2001-05-18-01:30:05-BST
jlarmour
parents: 115
diff changeset
153
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
154 obase=base;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
155 osize=size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
156
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
157 alignment = align;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
158 while (alignment < (cyg_int32)sizeof(struct memdq))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
159 alignment += alignment;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
160 CYG_ASSERT(0==(alignment & alignment-1),"alignment not a power of 2");
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
161
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
162 // the memdq for each allocation is always positioned immediately before
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
163 // an aligned address, so that the allocation (i.e. what eventually gets
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
164 // returned from alloc()) is at the correctly aligned address
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
165 // Therefore bottom is set to the lowest available address given the size of
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
166 // struct memdq and the alignment.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
167 bottom = (cyg_uint8 *)addr2memdq(base);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
168
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
169 // because we split free blocks by allocating memory from the end, not
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
170 // the beginning, then to preserve alignment, the *top* must also be
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
171 // aligned such that (top-bottom) is a multiple of the alignment
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
172 top = (cyg_uint8 *)((cyg_int32)(base+size+sizeof(struct memdq)) & -alignment) -
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
173 sizeof(struct memdq);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
174
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
175 CYG_ASSERT( top > bottom , "heap too small" );
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
176 CYG_ASSERT( top <= (base+size), "top too large" );
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
177 CYG_ASSERT( ((cyg_int32)(top+sizeof(struct memdq)) & alignment-1)==0,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
178 "top badly aligned" );
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
179
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
180 struct memdq *hdq = &head, *dq = (struct memdq *)bottom;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
181
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
182 CYG_ASSERT( ((cyg_int32)memdq2alloc(dq) & alignment-1)==0,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
183 "bottom badly aligned" );
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
184
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
185 hdq->prev = hdq->next = dq;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
186 hdq->size = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
187 dq->prev = dq->next = hdq;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
188
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
189 freemem = dq->size = top - bottom;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
190 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
191
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
192 // -------------------------------------------------------------------------
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
193
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
194 inline
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
195 Cyg_Mempool_Variable_Implementation::~Cyg_Mempool_Variable_Implementation()
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
196 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
197 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
198
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
199 // -------------------------------------------------------------------------
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
200 // allocation is simple
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
201 // First we look down the free list for a large enough block
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
202 // If we find a block the right size, we unlink the block from
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
203 // the free list and return a pointer to it.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
204 // If we find a larger block, we chop a piece off the end
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
205 // and return that
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
206 // Otherwise we will eventually get back to the head of the list
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
207 // and return NULL
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
208 inline cyg_uint8 *
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
209 Cyg_Mempool_Variable_Implementation::try_alloc( cyg_int32 size )
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
210 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
211 struct memdq *dq = &head;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
212 cyg_uint8 *alloced;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
213
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
214 CYG_REPORT_FUNCTION();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
215
159
511f4dc167f6 Merge from eCos master repository on 2001-05-18-01:30:05-BST
jlarmour
parents: 115
diff changeset
216 // Allow uninitialised (zero sized) heaps because they could exist as a
511f4dc167f6 Merge from eCos master repository on 2001-05-18-01:30:05-BST
jlarmour
parents: 115
diff changeset
217 // quirk of the MLT setup where a dynamically sized heap is at the top of
511f4dc167f6 Merge from eCos master repository on 2001-05-18-01:30:05-BST
jlarmour
parents: 115
diff changeset
218 // memory.
511f4dc167f6 Merge from eCos master repository on 2001-05-18-01:30:05-BST
jlarmour
parents: 115
diff changeset
219 if (NULL == bottom)
511f4dc167f6 Merge from eCos master repository on 2001-05-18-01:30:05-BST
jlarmour
parents: 115
diff changeset
220 return NULL;
511f4dc167f6 Merge from eCos master repository on 2001-05-18-01:30:05-BST
jlarmour
parents: 115
diff changeset
221
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
222 size = roundup(size);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
223
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
224 do {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
225 CYG_ASSERT( dq->next->prev==dq, "Bad link in dq");
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
226 dq = dq->next;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
227 if(0 == dq->size) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
228 CYG_ASSERT(dq == &head, "bad free block");
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
229 return NULL;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
230 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
231 } while(dq->size < size);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
232
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
233 if( size == dq->size ) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
234 // exact fit -- unlink from free list
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
235 dq->prev->next = dq->next;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
236 dq->next->prev = dq->prev;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
237 alloced = (cyg_uint8 *)dq;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
238 } else {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
239
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
240 CYG_ASSERT( dq->size > size, "block found is too small");
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
241
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
242 // allocate portion of memory from end of block
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
243
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
244 dq->size -=size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
245
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
246 // The portion left over has to be large enough to store a
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
247 // struct memdq. This is guaranteed because the alignment is
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
248 // larger than the size of this structure.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
249
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
250 CYG_ASSERT( (cyg_int32)sizeof(struct memdq)<=dq->size ,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
251 "not enough space for list item" );
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
252
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
253 alloced = (cyg_uint8 *)dq + dq->size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
254 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
255
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
256 CYG_ASSERT( bottom<=alloced && alloced<=top, "alloced outside pool" );
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
257
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
258 // Set size on allocated block
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
259
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
260 dq = (struct memdq *)alloced;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
261 dq->size = size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
262 dq->next = dq->prev = (struct memdq *)0xd530d53; // magic number
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
263
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
264 freemem -=size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
265
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
266 cyg_uint8 *ptr = memdq2alloc( dq );
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
267 CYG_ASSERT( ((CYG_ADDRESS)ptr & (alignment-1)) == 0,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
268 "returned memory not aligned" );
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
269 return ptr;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
270 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
271
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
272 // -------------------------------------------------------------------------
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
273 // resize existing allocation, if oldsize is non-NULL, previous
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
274 // allocation size is placed into it. If previous size not available,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
275 // it is set to 0. NB previous allocation size may have been rounded up.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
276 // Occasionally the allocation can be adjusted *backwards* as well as,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
277 // or instead of forwards, therefore the address of the resized
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
278 // allocation is returned, or NULL if no resizing was possible.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
279 // Note that this differs from ::realloc() in that no attempt is
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
280 // made to call malloc() if resizing is not possible - that is left
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
281 // to higher layers. The data is copied from old to new though.
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
282 // The effects of alloc_ptr==NULL or newsize==0 are undefined
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
283
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
284 inline cyg_uint8 *
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
285 Cyg_Mempool_Variable_Implementation::resize_alloc( cyg_uint8 *alloc_ptr,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
286 cyg_int32 newsize,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
287 cyg_int32 *oldsize )
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
288 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
289 cyg_uint8 *ret = NULL;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
290
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
291 CYG_REPORT_FUNCTION();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
292
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
293 CYG_CHECK_DATA_PTRC( alloc_ptr );
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
294 if ( NULL != oldsize )
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
295 CYG_CHECK_DATA_PTRC( oldsize );
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
296
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
297 CYG_ASSERT( (bottom <= alloc_ptr) && (alloc_ptr <= top),
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
298 "alloc_ptr outside pool" );
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
299
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
300 struct memdq *dq=alloc2memdq( alloc_ptr );
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
301
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
302 // check magic number in block for validity
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
303 CYG_ASSERT( (dq->next == dq->prev) &&
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
304 (dq->next == (struct memdq *)0xd530d53), "bad alloc_ptr" );
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
305
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
306 newsize = roundup(newsize);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
307
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
308 if ( NULL != oldsize )
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
309 *oldsize = dq->size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
310
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
311 if ( newsize > dq->size ) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
312 // see if we can increase the allocation size
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
313 if ( (cyg_uint8 *)dq + newsize <= top ) { // obviously can't exceed pool
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
314 struct memdq *nextdq = (struct memdq *)((cyg_uint8 *)dq + dq->size);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
315
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
316 if ( (nextdq->next != nextdq->prev) &&
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
317 (nextdq->size >= (newsize - dq->size)) ) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
318 // it's free and it's big enough
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
319 // we therefore temporarily join this block and *all* of
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
320 // the next block, so that the code below can then split it
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
321 nextdq->next->prev = nextdq->prev;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
322 nextdq->prev->next = nextdq->next;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
323 dq->size += nextdq->size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
324 freemem -= nextdq->size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
325 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
326 } // if
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
327 } // if
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
328
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
329 // this is also used if the allocation size was increased and we need
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
330 // to split it
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
331 if ( newsize < dq->size ) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
332 // We can shrink the allocation by splitting into smaller allocation and
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
333 // new free block
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
334 struct memdq *newdq = (struct memdq *)((cyg_uint8 *)dq + newsize);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
335
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
336 newdq->size = dq->size - newsize;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
337 dq->size = newsize;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
338
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
339 CYG_ASSERT( (cyg_int32)sizeof(struct memdq)<=newdq->size ,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
340 "not enough space for list item" );
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
341
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
342 // now return the new space back to the freelist
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
343 insert_free_block( newdq );
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
344
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
345 ret = alloc_ptr;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
346
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
347 } // if
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
348 else if ( newsize == dq->size ) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
349 ret = alloc_ptr;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
350 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
351
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
352 return ret;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
353
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
354 } // resize_alloc()
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
355
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
356
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
357 // -------------------------------------------------------------------------
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
358 // When no coalescing is done, free is simply a matter of using the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
359 // freed memory as an element of the free list linking it in at the
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
360 // start. When coalescing, the free list is sorted
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
361
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
362 inline cyg_bool
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
363 Cyg_Mempool_Variable_Implementation::free( cyg_uint8 *p, cyg_int32 size )
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
364 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
365 CYG_REPORT_FUNCTION();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
366
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
367 CYG_CHECK_DATA_PTRC( p );
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
368
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
369 if (!((bottom <= p) && (p <= top)))
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
370 return false;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
371
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
372 struct memdq *dq=alloc2memdq( p );
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
373
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
374 // check magic number in block for validity
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
375 if ( (dq->next != dq->prev) ||
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
376 (dq->next != (struct memdq *)0xd530d53) )
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
377 return false;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
378
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
379 if ( 0==size ) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
380 size = dq->size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
381 } else {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
382 size = roundup(size);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
383 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
384
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
385 if( dq->size != size )
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
386 return false;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
387
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
388 CYG_ASSERT( (cyg_int32)sizeof(struct memdq)<=size ,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
389 "not enough space for list item" );
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
390
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
391 insert_free_block( dq );
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
392
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
393 return true;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
394 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
395
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
396 // -------------------------------------------------------------------------
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
397
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
398 inline void
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
399 Cyg_Mempool_Variable_Implementation::get_status(
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
400 cyg_mempool_status_flag_t flags,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
401 Cyg_Mempool_Status &status )
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
402 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
403 CYG_REPORT_FUNCTION();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
404
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
405 // as quick or quicker to just set it, rather than test flag first
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
406 status.arenabase = obase;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
407 if ( 0 != (flags & CYG_MEMPOOL_STAT_ARENASIZE) )
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
408 status.arenasize = top - bottom;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
409 if ( 0 != (flags & CYG_MEMPOOL_STAT_TOTALALLOCATED) )
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
410 status.totalallocated = (top-bottom) - freemem;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
411 // as quick or quicker to just set it, rather than test flag first
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
412 status.totalfree = freemem;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
413 if ( 0 != (flags & CYG_MEMPOOL_STAT_MAXFREE) ) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
414 struct memdq *dq = &head;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
415 cyg_int32 mf = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
416
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
417 do {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
418 CYG_ASSERT( dq->next->prev==dq, "Bad link in dq");
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
419 dq = dq->next;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
420 if(0 == dq->size) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
421 CYG_ASSERT(dq == &head, "bad free block");
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
422 break;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
423 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
424 if(dq->size > mf)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
425 mf = dq->size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
426 } while(1);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
427 status.maxfree = mf;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
428 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
429 // as quick or quicker to just set it, rather than test flag first
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
430 status.origbase = obase;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
431 // as quick or quicker to just set it, rather than test flag first
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
432 status.origsize = osize;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
433
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
434 CYG_REPORT_RETURN();
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
435
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
436 } // get_status()
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
437
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
438
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
439 // -------------------------------------------------------------------------
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
440 #endif // ifndef CYGONCE_MEMALLOC_MVARIMPL_INL
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
441 // EOF mvarimpl.inl