Contiki 3.x
mmem.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2005, Swedish Institute of Computer Science
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  *
31  */
32 
33 /**
34  * \addtogroup mmem
35  * @{
36  */
37 
38 /**
39  * \file
40  * Implementation of the managed memory allocator
41  * \author
42  * Adam Dunkels <adam@sics.se>
43  *
44  */
45 
46 
47 #include "mmem.h"
48 #include "list.h"
49 #include "contiki-conf.h"
50 #include <string.h>
51 
52 #ifdef MMEM_CONF_SIZE
53 #define MMEM_SIZE MMEM_CONF_SIZE
54 #else
55 #define MMEM_SIZE 4096
56 #endif
57 
58 LIST(mmemlist);
59 unsigned int avail_memory;
60 static char memory[MMEM_SIZE];
61 
62 /*---------------------------------------------------------------------------*/
63 /**
64  * \brief Allocate a managed memory block
65  * \param m A pointer to a struct mmem.
66  * \param size The size of the requested memory block
67  * \return Non-zero if the memory could be allocated, zero if memory
68  * was not available.
69  * \author Adam Dunkels
70  *
71  * This function allocates a chunk of managed memory. The
72  * memory allocated with this function must be deallocated
73  * using the mmem_free() function.
74  *
75  * \note This function does NOT return a pointer to the
76  * allocated memory, but a pointer to a structure that
77  * contains information about the managed memory. The
78  * macro MMEM_PTR() is used to get a pointer to the
79  * allocated memory.
80  *
81  */
82 int
83 mmem_alloc(struct mmem *m, unsigned int size)
84 {
85  /* Check if we have enough memory left for this allocation. */
86  if(avail_memory < size) {
87  return 0;
88  }
89 
90  /* We had enough memory so we add this memory block to the end of
91  the list of allocated memory blocks. */
92  list_add(mmemlist, m);
93 
94  /* Set up the pointer so that it points to the first available byte
95  in the memory block. */
96  m->ptr = &memory[MMEM_SIZE - avail_memory];
97 
98  /* Remember the size of this memory block. */
99  m->size = size;
100 
101  /* Decrease the amount of available memory. */
102  avail_memory -= size;
103 
104  /* Return non-zero to indicate that we were able to allocate
105  memory. */
106  return 1;
107 }
108 /*---------------------------------------------------------------------------*/
109 /**
110  * \brief Deallocate a managed memory block
111  * \param m A pointer to the managed memory block
112  * \author Adam Dunkels
113  *
114  * This function deallocates a managed memory block that
115  * previously has been allocated with mmem_alloc().
116  *
117  */
118 void
119 mmem_free(struct mmem *m)
120 {
121  struct mmem *n;
122 
123  if(m->next != NULL) {
124  /* Compact the memory after the allocation that is to be removed
125  by moving it downwards. */
126  memmove(m->ptr, m->next->ptr,
127  &memory[MMEM_SIZE - avail_memory] - (char *)m->next->ptr);
128 
129  /* Update all the memory pointers that points to memory that is
130  after the allocation that is to be removed. */
131  for(n = m->next; n != NULL; n = n->next) {
132  n->ptr = (void *)((char *)n->ptr - m->size);
133  }
134  }
135 
136  avail_memory += m->size;
137 
138  /* Remove the memory block from the list. */
139  list_remove(mmemlist, m);
140 }
141 /*---------------------------------------------------------------------------*/
142 /**
143  * \brief Initialize the managed memory module
144  * \author Adam Dunkels
145  *
146  * This function initializes the managed memory module and
147  * should be called before any other function from the
148  * module.
149  *
150  */
151 void
153 {
154  list_init(mmemlist);
155  avail_memory = MMEM_SIZE;
156 }
157 /*---------------------------------------------------------------------------*/
158 
159 /** @} */
Linked list manipulation routines.
Header file for the managed memory allocator
void mmem_init(void)
Initialize the managed memory module.
Definition: mmem.c:152
#define NULL
The null pointer.
void list_remove(list_t list, void *item)
Remove a specific element from a list.
Definition: list.c:240
void list_init(list_t list)
Initialize a list.
Definition: list.c:66
void list_add(list_t list, void *item)
Add an item at the end of a list.
Definition: list.c:143
#define LIST(name)
Declare a linked list.
Definition: list.h:86
int mmem_alloc(struct mmem *m, unsigned int size)
Allocate a managed memory block.
Definition: mmem.c:83
void mmem_free(struct mmem *m)
Deallocate a managed memory block.
Definition: mmem.c:119