Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

virtmem.h

Go to the documentation of this file.
00001 // See the end of this file for license information.
00002 
00003 #ifndef TORSION_VIRTMEM_H
00004 #define TORSION_VIRTMEM_H
00005 
00006 #include "asm.h"
00007 
00008 class Virtual_memory;
00009 extern Virtual_memory virtual_mem;
00010 class Chunk;
00011 
00013 
00022 class Virtual_memory {
00023 protected:
00024   Chunk* curr_free_chunk;               
00025   Chunk* free_list_head;                
00026   Chunk* free_list_tail;                
00027 
00028 public:
00029   void* managed_mem_start;              
00030 
00032   void
00033   init();
00034 
00036   void*
00037   alloc(unsigned int request_size);
00038 
00040   void
00041   free(void* data_address);
00042 };
00043 
00046 
00047 class Chunk {
00048 protected:
00049   unsigned int size_and_flags;          
00050 
00051 
00052 public:
00053   Chunk* forward;                       
00054 
00055   Chunk* back;                          
00056 
00057   static const unsigned int PREV_IN_USE = 1<<0;
00058   static const unsigned int NEXT_IN_USE = 1<<1;
00059   static const unsigned int STATUS_MASK = PREV_IN_USE | NEXT_IN_USE;
00060   static const unsigned int SIZE_MASK = ~STATUS_MASK;
00061   static const unsigned int ALIGNMENT = sizeof(unsigned int) - 1;
00062   static const unsigned int USED_HEADER_SIZE = sizeof(unsigned int);
00063   static const unsigned int UNUSED_HEADER_SIZE = USED_HEADER_SIZE +
00064                                                  sizeof(Chunk*) * 2;
00065   static const unsigned int FOOTER_SIZE = sizeof(unsigned int);
00066 
00068   inline void
00069   set_size(unsigned int chunk_size, bool previous_in_use, bool next_in_use) {
00070     unsigned int flags = 0;             // set header chunk size/flags tag
00071     if (previous_in_use) flags |= PREV_IN_USE;
00072     if (next_in_use) flags |= NEXT_IN_USE;
00073     size_and_flags = (chunk_size & SIZE_MASK) | flags;
00074                                         // set footer chunk size tag
00075     *((unsigned int*)((unsigned char*)this + size()) - 1) = size();
00076   }
00077 
00079   inline void
00080   set_previous_in_use(bool previous_in_use) {
00081     if (previous_in_use)
00082       size_and_flags |= PREV_IN_USE;
00083     else
00084       size_and_flags &= ~PREV_IN_USE;
00085   }
00086   
00088   inline void
00089   set_next_in_use(bool next_in_use) {
00090     if (next_in_use)
00091       size_and_flags |= NEXT_IN_USE;
00092     else
00093       size_and_flags &= ~NEXT_IN_USE;
00094   }
00095   
00097   inline unsigned int
00098   size() {
00099     return size_and_flags & SIZE_MASK;
00100   }
00101 
00103   inline unsigned int
00104   previous_size() {
00105     return *((unsigned int*)this - 1);
00106   }
00107   
00109   inline Chunk*
00110   previous_chunk() {
00111     Chunk* prior_chunk = (Chunk*)((unsigned char*)this - previous_size());
00112     if ((void*)prior_chunk < virtual_mem.managed_mem_start)
00113       return NULL;
00114     return prior_chunk;
00115   }
00116   
00118   inline Chunk*
00119   next_chunk() {
00120     Chunk* subsequent_chunk = (Chunk*)((unsigned char*)this + size());
00121     if (subsequent_chunk < this)        // check for wrap-around
00122       return NULL;
00123     return subsequent_chunk;
00124   }
00125 
00127   inline bool
00128   is_previous_in_use() {
00129     if (size_and_flags & PREV_IN_USE)
00130       return true;
00131     return false;
00132   }
00133   
00135   inline bool
00136   is_next_in_use() {
00137     if (size_and_flags & NEXT_IN_USE)
00138       return true;
00139     return false;
00140   }
00141 
00144   inline void*
00145   data_address() {
00146     return (unsigned char*)this + USED_HEADER_SIZE;
00147   }
00148 
00151   static inline Chunk*
00152   convert_data_address_to_chunk(void* data_address) {
00153     return (Chunk*)((unsigned char*)data_address - USED_HEADER_SIZE);
00154   }
00155 
00157   static inline unsigned int
00158   align(unsigned int byte_size) {
00159     if (byte_size & ALIGNMENT)          // if unaligned, align it (round up)
00160       return (byte_size & ~ALIGNMENT) + ALIGNMENT + 1;
00161     return byte_size;
00162   }
00163 
00165   static inline void*
00166   align(void* address) {
00167     return (void*)Chunk::align((unsigned int)address);
00168   }
00169 };
00170 
00171 #endif
00172 
00173 /* Torsion Operating System, Copyright (C) 2000-2002 Dan Helfman
00174  *
00175  * This program is free software; you can redistribute it and/or modify it
00176  * under the terms of the GNU General Public License as published by the
00177  * Free Software Foundation; either version 2 of the License, or (at your
00178  * option) any later version.
00179  * 
00180  * This program is distributed in the hope that it will be useful, but
00181  * WITHOUT ANY WARRANTY; without even the implied warranty of
00182  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00183  * General Public License for more details (in the COPYING file).
00184  * 
00185  * You should have received a copy of the GNU General Public License along
00186  * with this program; if not, write to the Free Software Foundation, Inc.,
00187  * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00188  */

Torsion Operating System, Copyright (C) 2000-2002 Dan Helfman