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.1 2006/06/17 22:41:18 adamdunkels 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 00051 #include <string.h> 00052 00053 #define MMEM_SIZE 4096 00054 00055 LIST(mmemlist); 00056 unsigned int avail_memory; 00057 static char memory[MMEM_SIZE]; 00058 00059 /*---------------------------------------------------------------------------*/ 00060 /** 00061 * \brief Allocate a managed memory block 00062 * \param m A pointer to a struct mmem. 00063 * \param size The size of the requested memory block 00064 * \return Non-zero if the memory could be allocated, zero if memory 00065 * was not available. 00066 * \author Adam Dunkels 00067 * 00068 * This function allocates a chunk of managed memory. The 00069 * memory allocated with this function must be deallocated 00070 * using the mmem_free() function. 00071 * 00072 * \note This function does NOT return a pointer to the 00073 * allocated memory, but a pointer to a structure that 00074 * contains information about the managed memory. The 00075 * macro MMEM_PTR() is used to get a pointer to the 00076 * allocated memory. 00077 * 00078 */ 00079 int 00080 mmem_alloc(struct mmem *m, unsigned int size) 00081 { 00082 /* Check if we have enough memory left for this allocation. */ 00083 if(avail_memory < size) { 00084 return 0; 00085 } 00086 00087 /* We had enough memory so we add this memory block to the end of 00088 the list of allocated memory blocks. */ 00089 list_add(mmemlist, m); 00090 00091 /* Set up the pointer so that it points to the first available byte 00092 in the memory block. */ 00093 m->ptr = &memory[MMEM_SIZE - avail_memory]; 00094 00095 /* Remember the size of this memory block. */ 00096 m->size = size; 00097 00098 /* Decrease the amount of available memory. */ 00099 avail_memory -= size; 00100 00101 /* Return non-zero to indicate that we were able to allocate 00102 memory. */ 00103 return 1; 00104 } 00105 /*---------------------------------------------------------------------------*/ 00106 /** 00107 * \brief Deallocate a managed memory block 00108 * \param m A pointer to the managed memory block 00109 * \author Adam Dunkels 00110 * 00111 * This function deallocates a managed memory block that 00112 * previously has been allocated with mmem_alloc(). 00113 * 00114 */ 00115 void 00116 mmem_free(struct mmem *m) 00117 { 00118 struct mmem *n; 00119 00120 if(m->next != NULL) { 00121 /* Compact the memory after the allocation that is to be removed 00122 by moving it downwards. */ 00123 memmove(m->ptr, m->next->ptr, 00124 &memory[MMEM_SIZE - avail_memory] - (char *)m->next->ptr); 00125 00126 /* Update all the memory pointers that points to memory that is 00127 after the allocation that is to be removed. */ 00128 for(n = m->next; n != NULL; n = n->next) { 00129 n->ptr = (void *)((char *)n->ptr - m->size); 00130 } 00131 } 00132 00133 avail_memory += m->size; 00134 00135 /* Remove the memory block from the list. */ 00136 list_remove(mmemlist, m); 00137 } 00138 /*---------------------------------------------------------------------------*/ 00139 /** 00140 * \brief Initialize the managed memory module 00141 * \author Adam Dunkels 00142 * 00143 * This function initializes the managed memory module and 00144 * should be called before any other function from the 00145 * module. 00146 * 00147 */ 00148 void 00149 mmem_init(void) 00150 { 00151 list_init(mmemlist); 00152 avail_memory = MMEM_SIZE; 00153 } 00154 /*---------------------------------------------------------------------------*/ 00155 00156 /** @} */