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