Rev Author Line No. Line
3328 povik 1 /**
2 * \addtogroup exampleapps
3 * @{
4 */
5  
6 /**
7 * \file
8 * Memory block allocation routines.
9 * \author Adam Dunkels <adam@sics.se>
10 *
11 * The memory block allocation routines provide a simple yet powerful
12 * set of functions for managing a set of memory blocks of fixed
13 * size. A set of memory blocks is statically declared with the
14 * MEMB() macro. Memory blocks are allocated from the declared
15 * memory by the memb_alloc() function, and are deallocated with the
16 * memb_free() function.
17 *
18 * \note Because of namespace clashes only one MEMB() can be
19 * declared per C module, and the name scope of a MEMB() memory
20 * block is local to each C module.
21 *
22 * The following example shows how to declare and use a memory block
23 * called "cmem" which has 8 chunks of memory with each memory chunk
24 * being 20 bytes large.
25 *
26 \code
27 MEMB(cmem, 20, 8);
28  
29 int main(int argc, char *argv[]) {
30 char *ptr;
31  
32 memb_init(&cmem);
33  
34 ptr = memb_alloc(&cmem);
35  
36 if(ptr != NULL) {
37 do_something(ptr);
38 } else {
39 printf("Could not allocate memory.\n");
40 }
41  
42 if(memb_free(ptr) == 0) {
43 printf("Deallocation succeeded.\n");
44 }
45 }
46 \endcode
47 *
48 */
49  
50 #include <string.h>
51  
52 #include "memb.h"
53  
54 /*------------------------------------------------------------------------------*/
55 /**
56 * Initialize a memory block that was declared with MEMB().
57 *
58 * \param m A memory block previosly declared with MEMB().
59 */
60 /*------------------------------------------------------------------------------*/
61 void
62 memb_init(struct memb_blocks *m)
63 {
64 memset(m->mem, (m->size + 1) * m->num, 0);
65 }
66 /*------------------------------------------------------------------------------*/
67 /**
68 * Allocate a memory block from a block of memory declared with MEMB().
69 *
70 * \param m A memory block previosly declared with MEMB().
71 */
72 /*------------------------------------------------------------------------------*/
73 char *
74 memb_alloc(struct memb_blocks *m)
75 {
76 int i;
77 char *ptr;
78  
79 ptr = m->mem;
80 for(i = 0; i < m->num; ++i) {
81 if(*ptr == 0) {
82 /* If this block was unused, we increase the reference count to
83 indicate that it now is used and return a pointer to the
84 first byte following the reference counter. */
85 ++*ptr;
86 return ptr + 1;
87 }
88 ptr += m->size + 1;
89 }
90  
91 /* No free block was found, so we return NULL to indicate failure to
92 allocate block. */
93 return NULL;
94 }
95 /*------------------------------------------------------------------------------*/
96 /**
97 * Deallocate a memory block from a memory block previously declared
98 * with MEMB().
99 *
100 * \param m m A memory block previosly declared with MEMB().
101 *
102 * \param ptr A pointer to the memory block that is to be deallocated.
103 *
104 * \return The new reference count for the memory block (should be 0
105 * if successfully deallocated) or -1 if the pointer "ptr" did not
106 * point to a legal memory block.
107 */
108 /*------------------------------------------------------------------------------*/
109 char
110 memb_free(struct memb_blocks *m, char *ptr)
111 {
112 int i;
113 char *ptr2;
114  
115 /* Walk through the list of blocks and try to find the block to
116 which the pointer "ptr" points to. */
117 ptr2 = m->mem;
118 for(i = 0; i < m->num; ++i) {
119  
120 if(ptr2 == ptr - 1) {
121 /* We've found to block to which "ptr" points so we decrease the
122 reference count and return the new value of it. */
123 return --*ptr2;
124 }
125 ptr2 += m->size + 1;
126 }
127 return -1;
128 }
129 /*------------------------------------------------------------------------------*/
130 /**
131 * Increase the reference count for a memory chunk.
132 *
133 * \note No sanity checks are currently made.
134 *
135 * \param m m A memory block previosly declared with MEMB().
136 *
137 * \param ptr A pointer to the memory chunk for which the reference
138 * count should be increased.
139 *
140 * \return The new reference count.
141 */
142 /*------------------------------------------------------------------------------*/
143 char
144 memb_ref(struct memb_blocks *m, char *ptr)
145 {
146 return ++*(ptr - 1);
147 }
148 /*------------------------------------------------------------------------------*/
149  
150  
151  
152