Browse Source

Removed win-only component of line endings

master
Patrick Jakobsen 7 years ago
parent
commit
8fa0bafeed
  1. 282
      src/acs_source/ZMEMORY.acs

282
src/acs_source/ZMEMORY.acs

@ -1,64 +1,64 @@
#library "ZMEMORY" #library "ZMEMORY"
#include "zcommon.acs" #include "zcommon.acs"
//Simple linked list implementation of malloc //Simple linked list implementation of malloc
global int 63:memory[]; global int 63:memory[];
#libdefine nullptr 0 #libdefine nullptr 0
#define malloc_allocated 0 #define malloc_allocated 0
#define malloc_size 1 #define malloc_size 1
#define malloc_next_header 2 #define malloc_next_header 2
#define malloc_prev_header 3 #define malloc_prev_header 3
#define malloc_num_header_properties 4 #define malloc_num_header_properties 4
#define p_malloc_init_flag_location 0 #define p_malloc_init_flag_location 0
#define p_malloc_first_header_location 1 #define p_malloc_first_header_location 1
function int malloc (int size) { function int malloc (int size) {
log(s:"Invoked malloc"); log(s:"Invoked malloc");
//Do the setup on the first run of this function. //Do the setup on the first run of this function.
if(memory[p_malloc_init_flag_location] == FALSE) { //Default values for global values is 0, so this is true. if(memory[p_malloc_init_flag_location] == FALSE) { //Default values for global values is 0, so this is true.
memory[p_malloc_init_flag_location] = TRUE; memory[p_malloc_init_flag_location] = TRUE;
memory[p_malloc_first_header_location+malloc_allocated] = FALSE; memory[p_malloc_first_header_location+malloc_allocated] = FALSE;
memory[p_malloc_first_header_location+malloc_size] = -1; //"infinite" memory[p_malloc_first_header_location+malloc_size] = -1; //"infinite"
memory[p_malloc_first_header_location+malloc_next_header] = nullptr; //nullptr memory[p_malloc_first_header_location+malloc_next_header] = nullptr; //nullptr
memory[p_malloc_first_header_location+malloc_prev_header] = nullptr; //nullptr memory[p_malloc_first_header_location+malloc_prev_header] = nullptr; //nullptr
} }
int p_previous_header = nullptr; int p_previous_header = nullptr;
int p_current_header = p_malloc_first_header_location; int p_current_header = p_malloc_first_header_location;
int p_retval = nullptr; int p_retval = nullptr;
while(p_retval == nullptr) { while(p_retval == nullptr) {
int memalloced = memory[p_current_header+malloc_allocated]; int memalloced = memory[p_current_header+malloc_allocated];
int memsize = memory[p_current_header+malloc_size]; int memsize = memory[p_current_header+malloc_size];
if(memsize == -1) { //The end of the list. if(memsize == -1) { //The end of the list.
memory[p_current_header+malloc_allocated] = TRUE; memory[p_current_header+malloc_allocated] = TRUE;
memory[p_current_header+malloc_size] = size; memory[p_current_header+malloc_size] = size;
memory[p_current_header+malloc_next_header] = p_current_header+malloc_num_header_properties+size; //New EOL memory[p_current_header+malloc_next_header] = p_current_header+malloc_num_header_properties+size; //New EOL
memory[p_current_header+malloc_prev_header] = p_previous_header; memory[p_current_header+malloc_prev_header] = p_previous_header;
//Retrieve the return value while we are at the allocated space. //Retrieve the return value while we are at the allocated space.
p_retval = p_current_header+malloc_num_header_properties; p_retval = p_current_header+malloc_num_header_properties;
//Remember to initialize the new end list node. //Remember to initialize the new end list node.
p_previous_header = p_current_header; //This is the header previous to the EOL. p_previous_header = p_current_header; //This is the header previous to the EOL.
p_current_header = memory[p_current_header+malloc_next_header]; p_current_header = memory[p_current_header+malloc_next_header];
//Set the tail node constants. //Set the tail node constants.
memory[p_current_header+malloc_allocated] = FALSE; memory[p_current_header+malloc_allocated] = FALSE;
memory[p_current_header+malloc_size] = -1; memory[p_current_header+malloc_size] = -1;
memory[p_current_header+malloc_next_header] = nullptr; memory[p_current_header+malloc_next_header] = nullptr;
memory[p_current_header+malloc_prev_header] = p_previous_header; memory[p_current_header+malloc_prev_header] = p_previous_header;
} else if(memsize >= size && memalloced == FALSE) { //There is room here AND it isn't in use, } else if(memsize >= size && memalloced == FALSE) { //There is room here AND it isn't in use,
memory[p_current_header+malloc_allocated] = TRUE; memory[p_current_header+malloc_allocated] = TRUE;
//The size isn't modified because we are re-using an existing space. //The size isn't modified because we are re-using an existing space.
// It would be a good idea to check just how large this space is and act accordingly rather // It would be a good idea to check just how large this space is and act accordingly rather
// than using a 500 indexes large space for a 4 indexes large object. // than using a 500 indexes large space for a 4 indexes large object.
// Objects allocated in a doom mod probably won't be outside the 1-16 indexes range so it // Objects allocated in a doom mod probably won't be outside the 1-16 indexes range so it
// should still be fine for most applications. // should still be fine for most applications.
//The next header isn't changed either for the same reason. //The next header isn't changed either for the same reason.
if(memsize >= (size+malloc_num_header_properties+5)) { //Assume that 5 is the smallest useful allocation size. if(memsize >= (size+malloc_num_header_properties+5)) { //Assume that 5 is the smallest useful allocation size.
int p_split_newheader = p_current_header+malloc_num_header_properties+size; //Just to the end of the allocation. int p_split_newheader = p_current_header+malloc_num_header_properties+size; //Just to the end of the allocation.
memory[p_split_newheader+malloc_allocated] = FALSE; memory[p_split_newheader+malloc_allocated] = FALSE;
@ -68,89 +68,89 @@ function int malloc (int size) {
memory[p_current_header+malloc_next_header] = p_split_newheader; //The header whose block was split should have its next pointer set to its other half. memory[p_current_header+malloc_next_header] = p_split_newheader; //The header whose block was split should have its next pointer set to its other half.
memory[p_current_header+malloc_size] = size; //Set the size of the allocation to reflect the split. memory[p_current_header+malloc_size] = size; //Set the size of the allocation to reflect the split.
} }
//Retrieve the return value while we are at the allocated space. //Retrieve the return value while we are at the allocated space.
p_retval = p_current_header+malloc_num_header_properties; p_retval = p_current_header+malloc_num_header_properties;
} else { } else {
//The observed node isn't useful for allocating the request. Go to the next node. //The observed node isn't useful for allocating the request. Go to the next node.
p_previous_header = p_current_header; p_previous_header = p_current_header;
p_current_header = memory[p_current_header+malloc_next_header]; p_current_header = memory[p_current_header+malloc_next_header];
} }
} }
log(s:"Malloc allocated ", d:size, s:" indexes at location ", d:p_retval, s:" with header location ", d:p_current_header); log(s:"Malloc allocated ", d:size, s:" indexes at location ", d:p_retval, s:" with header location ", d:p_current_header);
return p_retval; return p_retval;
} }
function int free (int p_ptr) { function int free (int p_ptr) {
log(s:"Invoked free"); log(s:"Invoked free");
int p_header = p_ptr - malloc_num_header_properties; int p_header = p_ptr - malloc_num_header_properties;
memory[p_header+malloc_allocated] = FALSE; memory[p_header+malloc_allocated] = FALSE;
int p_next = memory[p_header+malloc_next_header]; int p_next = memory[p_header+malloc_next_header];
int p_prev = memory[p_header+malloc_prev_header]; int p_prev = memory[p_header+malloc_prev_header];
//Below is the merging of free blocks. //Below is the merging of free blocks.
//It merges to the left (lower indexes) first becaue the right (larger //It merges to the left (lower indexes) first becaue the right (larger
// indexes) has a special case. (the end of the list) // indexes) has a special case. (the end of the list)
//the previous block is unused. Merge. //the previous block is unused. Merge.
if(p_prev != nullptr //This doesn't make sense if the previous block doesn't exist. if(p_prev != nullptr //This doesn't make sense if the previous block doesn't exist.
&& memory[p_prev+malloc_allocated] == FALSE) { && memory[p_prev+malloc_allocated] == FALSE) {
log(s:"Free attempting merge of header ", d:p_header, s: " to the left with header ", d:p_prev); log(s:"Free attempting merge of header ", d:p_header, s: " to the left with header ", d:p_prev);
memory[p_prev+malloc_size] += memory[p_header+malloc_size] + malloc_num_header_properties; memory[p_prev+malloc_size] += memory[p_header+malloc_size] + malloc_num_header_properties;
memory[p_prev+malloc_next_header] = p_next; //The prev header needs to know the new next. memory[p_prev+malloc_next_header] = p_next; //The prev header needs to know the new next.
memory[p_next+malloc_prev_header] = p_prev; //The next header needs to know the new prev. memory[p_next+malloc_prev_header] = p_prev; //The next header needs to know the new prev.
//Now the two blocks are the same block. requires new initializations of the //Now the two blocks are the same block. requires new initializations of the
// variables for the other check to function correctly. // variables for the other check to function correctly.
//The header is the result of the merge, and the prev is the one before it. //The header is the result of the merge, and the prev is the one before it.
p_header = p_prev; p_header = p_prev;
p_prev = memory[p_header+malloc_prev_header]; p_prev = memory[p_header+malloc_prev_header];
} }
//The next block is unused. Merge. //The next block is unused. Merge.
//Note that p_next will never be a nullptr with correct usage. //Note that p_next will never be a nullptr with correct usage.
if(memory[p_next+malloc_allocated] == FALSE) { if(memory[p_next+malloc_allocated] == FALSE) {
if(memory[p_next+malloc_size] == -1) { //EOL if(memory[p_next+malloc_size] == -1) { //EOL
memory[p_header+malloc_size] = -1; memory[p_header+malloc_size] = -1;
memory[p_header+malloc_next_header] = nullptr; memory[p_header+malloc_next_header] = nullptr;
} else { } else {
int p_next_next = memory[p_next+malloc_next_header]; int p_next_next = memory[p_next+malloc_next_header];
memory[p_header+malloc_size] += memory[p_next+malloc_size] + malloc_num_header_properties; memory[p_header+malloc_size] += memory[p_next+malloc_size] + malloc_num_header_properties;
memory[p_header+malloc_next_header] = p_next_next; //The header on the other side of the next header needs to know its new prev. memory[p_header+malloc_next_header] = p_next_next; //The header on the other side of the next header needs to know its new prev.
memory[p_next_next+malloc_prev_header] = p_header; //This header needs to know its new next. memory[p_next_next+malloc_prev_header] = p_header; //This header needs to know its new next.
} }
} }
return -1; return -1;
} }
//These are for debugging //These are for debugging
script "memory_write" (int index, int value) { script "memory_write" (int index, int value) {
memory[index] = value; memory[index] = value;
} }
script "memory_read" (int index) { script "memory_read" (int index) {
log(d:memory[index]); log(d:memory[index]);
} }
script "memory_print_allocation_list" (void) { script "memory_print_allocation_list" (void) {
int p_current_header = p_malloc_first_header_location; int p_current_header = p_malloc_first_header_location;
while(p_current_header != nullptr) { while(p_current_header != nullptr) {
log(s: "Header location: ", d:p_current_header, log(s: "Header location: ", d:p_current_header,
s:"\n Allocated flag: ", d:memory[p_current_header+malloc_allocated], s:"\n Allocated flag: ", d:memory[p_current_header+malloc_allocated],
s:"\n Allocation size: ", d:memory[p_current_header+malloc_size], s:"\n Allocation size: ", d:memory[p_current_header+malloc_size],
s:"\n Prev header pointer: ", d:memory[p_current_header+malloc_prev_header], s:"\n Prev header pointer: ", d:memory[p_current_header+malloc_prev_header],
s:"\n Next header pointer: ", d:memory[p_current_header+malloc_next_header], s:"\n Next header pointer: ", d:memory[p_current_header+malloc_next_header],
s:"\n" s:"\n"
); );
p_current_header = memory[p_current_header+malloc_next_header]; p_current_header = memory[p_current_header+malloc_next_header];
} }
} }

Loading…
Cancel
Save