00001 /* 00002 * Copyright (c) 2005, Swedish Institute of Computer Science 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the Institute nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 * 00029 * This file is part of the Contiki operating system. 00030 * 00031 * @(#)$Id: mmem.c,v 1.2 2006/12/22 17:14:06 barner Exp $ 00032 */ 00033 00034 /** 00035 * \addtogroup mmem 00036 * @{ 00037 */ 00038 00039 /** 00040 * \file 00041 * Implementation of the managed memory allocator 00042 * \author 00043 * Adam Dunkels <adam@sics.se> 00044 * 00045 */ 00046 00047 00048 #include "mmem.h" 00049 #include "list.h" 00050 #include "contiki-conf.h" 00051 #include <string.h> 00052 00053 #ifdef MMEM_CONF_SIZE 00054 #define MMEM_SIZE MMEM_CONF_SIZE 00055 #else 00056 #define MMEM_SIZE 4096 00057 #endif 00058 00059 LIST(mmemlist); 00060 unsigned int avail_memory; 00061 static char memory[MMEM_SIZE]; 00062 00063 /*---------------------------------------------------------------------------*/ 00064 /** 00065 * \brief Allocate a managed memory block 00066 * \param m A pointer to a struct mmem. 00067 * \param size The size of the requested memory block 00068 * \return Non-zero if the memory could be allocated, zero if memory 00069 * was not available. 00070 * \author Adam Dunkels 00071 * 00072 * This function allocates a chunk of managed memory. The 00073 * memory allocated with this function must be deallocated 00074 * using the mmem_free() function. 00075 * 00076 * \note This function does NOT return a pointer to the 00077 * allocated memory, but a pointer to a structure that 00078 * contains information about the managed memory. The 00079 * macro MMEM_PTR() is used to get a pointer to the 00080 * allocated memory. 00081 * 00082 */ 00083 int 00084 mmem_alloc(struct mmem *m, unsigned int size) 00085 { 00086 /* Check if we have enough memory left for this allocation. */ 00087 if(avail_memory < size) { 00088 return 0; 00089 } 00090 00091 /* We had enough memory so we add this memory block to the end of 00092 the list of allocated memory blocks. */ 00093 list_add(mmemlist, m); 00094 00095 /* Set up the pointer so that it points to the first available byte 00096 in the memory block. */ 00097 m->ptr = &memory[MMEM_SIZE - avail_memory]; 00098 00099 /* Remember the size of this memory block. */ 00100 m->size = size; 00101 00102 /* Decrease the amount of available memory. */ 00103 avail_memory -= size; 00104 00105 /* Return non-zero to indicate that we were able to allocate 00106 memory. */ 00107 return 1; 00108 } 00109 /*---------------------------------------------------------------------------*/ 00110 /** 00111 * \brief Deallocate a managed memory block 00112 * \param m A pointer to the managed memory block 00113 * \author Adam Dunkels 00114 * 00115 * This function deallocates a managed memory block that 00116 * previously has been allocated with mmem_alloc(). 00117 * 00118 */ 00119 void 00120 mmem_free(struct mmem *m) 00121 { 00122 struct mmem *n; 00123 00124 if(m->next != NULL) { 00125 /* Compact the memory after the allocation that is to be removed 00126 by moving it downwards. */ 00127 memmove(m->ptr, m->next->ptr, 00128 &memory[MMEM_SIZE - avail_memory] - (char *)m->next->ptr); 00129 00130 /* Update all the memory pointers that points to memory that is 00131 after the allocation that is to be removed. */ 00132 for(n = m->next; n != NULL; n = n->next) { 00133 n->ptr = (void *)((char *)n->ptr - m->size); 00134 } 00135 } 00136 00137 avail_memory += m->size; 00138 00139 /* Remove the memory block from the list. */ 00140 list_remove(mmemlist, m); 00141 } 00142 /*---------------------------------------------------------------------------*/ 00143 /** 00144 * \brief Initialize the managed memory module 00145 * \author Adam Dunkels 00146 * 00147 * This function initializes the managed memory module and 00148 * should be called before any other function from the 00149 * module. 00150 * 00151 */ 00152 void 00153 mmem_init(void) 00154 { 00155 list_init(mmemlist); 00156 avail_memory = MMEM_SIZE; 00157 } 00158 /*---------------------------------------------------------------------------*/ 00159 00160 /** @} */