aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Oliver <contact@pauloliver.dev>2024-02-29 02:29:14 +0100
committerPaul Oliver <contact@pauloliver.dev>2024-02-29 02:29:14 +0100
commit687f56226dc8a024ef560ee4b390a630819f437c (patch)
tree36fb00aaae469508ea9940bd581effb6e985bf6b /src
parent2b62fa482a7553c07e7664b736a646af35c1f72d (diff)
Removed Memory module's MEM_BLOCK_START flag.
[#28] This flag served no purpose except to facilitate rendering. However, performance has a higher priority so I've eliminated this feature. Block start rendering can still be implemented via other methods.
Diffstat (limited to 'src')
-rw-r--r--src/memory.c116
-rw-r--r--src/process.c32
2 files changed, 49 insertions, 99 deletions
diff --git a/src/memory.c b/src/memory.c
index 87fc7ee..1036152 100644
--- a/src/memory.c
+++ b/src/memory.c
@@ -12,8 +12,7 @@
static boolean g_is_init;
static uint32 g_order;
static uint32 g_size;
-static uint32 g_block_start_count;
-static uint32 g_allocated_count;
+static uint32 g_allocated;
static uint32 g_capacity;
static uint32 g_inst_counter[INST_COUNT];
static uint8_p g_memory;
@@ -45,8 +44,7 @@ void _sal_mem_quit(void)
g_is_init = FALSE;
g_order = 0;
g_size = 0;
- g_block_start_count = 0;
- g_allocated_count = 0;
+ g_allocated = 0;
g_capacity = 0;
memset(g_inst_counter, 0, sizeof(uint32) * INST_COUNT);
g_memory = NULL;
@@ -61,8 +59,7 @@ void _sal_mem_load_from(FILE *file)
fread(&g_is_init, sizeof(boolean), 1, file);
fread(&g_order, sizeof(uint32), 1, file);
fread(&g_size, sizeof(uint32), 1, file);
- fread(&g_block_start_count, sizeof(uint32), 1, file);
- fread(&g_allocated_count, sizeof(uint32), 1, file);
+ fread(&g_allocated, sizeof(uint32), 1, file);
fread(&g_capacity, sizeof(uint32), 1, file);
fread(g_inst_counter, sizeof(uint32), INST_COUNT, file);
g_memory = calloc(g_size, sizeof(uint8));
@@ -79,8 +76,7 @@ void _sal_mem_save_into(FILE *file)
fwrite(&g_is_init, sizeof(boolean), 1, file);
fwrite(&g_order, sizeof(uint32), 1, file);
fwrite(&g_size, sizeof(uint32), 1, file);
- fwrite(&g_block_start_count, sizeof(uint32), 1, file);
- fwrite(&g_allocated_count, sizeof(uint32), 1, file);
+ fwrite(&g_allocated, sizeof(uint32), 1, file);
fwrite(&g_capacity, sizeof(uint32), 1, file);
fwrite(g_inst_counter, sizeof(uint32), INST_COUNT, file);
fwrite(g_memory, sizeof(uint8), g_size, file);
@@ -90,8 +86,7 @@ void _sal_mem_save_into(FILE *file)
*/
UINT32_GETTER(mem, order)
UINT32_GETTER(mem, size)
-UINT32_GETTER(mem, block_start_count)
-UINT32_GETTER(mem, allocated_count)
+UINT32_GETTER(mem, allocated)
UINT32_GETTER(mem, capacity)
uint32 sal_mem_get_inst_count(uint8 inst)
@@ -110,7 +105,7 @@ boolean sal_mem_is_over_capacity(void)
out of the reaper queue!
*/
assert(g_is_init);
- return g_allocated_count > g_capacity;
+ return g_allocated > g_capacity;
}
boolean sal_mem_is_address_valid(uint32 address)
@@ -121,72 +116,45 @@ boolean sal_mem_is_address_valid(uint32 address)
return address < g_size;
}
-/* We declare a standard macro to test whether a specific FLAG is set on a given
-byte. Remember, a Salis byte contains a 5 bit instruction (of 32 possible) plus
-2 flags: BLOCK_START and ALLOCATED. These flags help organisms identify where
-there is free memory space to reproduce on.
-*/
-#define FLAG_TEST(name, flag) \
-boolean sal_mem_is_##name(uint32 address) \
-{ \
- assert(g_is_init); \
- assert(sal_mem_is_address_valid(address)); \
- return !!(g_memory[address] & flag); \
-}
-
-FLAG_TEST(block_start, BLOCK_START_FLAG)
-FLAG_TEST(allocated, ALLOCATED_FLAG)
-
-/* We define a standard macro for 'setting' one of the 3 FLAGS into a given
-memory address.
-*/
-#define FLAG_SETTER(name, flag) \
-void _sal_mem_set_##name(uint32 address) \
-{ \
- assert(g_is_init); \
- assert(sal_mem_is_address_valid(address)); \
-\
- if (!sal_mem_is_##name(address)) { \
- g_memory[address] ^= flag; \
- g_##name##_count++; \
- } \
+boolean sal_mem_is_allocated(uint32 address)
+{
+ /* Check if given address is allocated.
+ */
+ assert(g_is_init);
+ assert(sal_mem_is_address_valid(address));
+ return !!(g_memory[address] & ALLOCATED_FLAG);
}
-FLAG_SETTER(block_start, BLOCK_START_FLAG)
-FLAG_SETTER(allocated, ALLOCATED_FLAG)
+void _sal_mem_set_allocated(uint32 address)
+{
+ /* Set allocated flag on a given address.
+ */
+ assert(g_is_init);
+ assert(sal_mem_is_address_valid(address));
-/* We define a standard macro for 'unsetting' one of the 3 FLAGS into a given
-memory address.
-*/
-#define FLAG_UNSETTER(name, flag) \
-void _sal_mem_unset_##name(uint32 address) \
-{ \
- assert(g_is_init); \
- assert(sal_mem_is_address_valid(address)); \
-\
- if (sal_mem_is_##name(address)) { \
- g_memory[address] ^= flag; \
- g_##name##_count--; \
- } \
+ if (!sal_mem_is_allocated(address)) {
+ g_memory[address] ^= ALLOCATED_FLAG;
+ g_allocated++;
+ }
}
-FLAG_UNSETTER(block_start, BLOCK_START_FLAG)
-FLAG_UNSETTER(allocated, ALLOCATED_FLAG)
-
-uint8 sal_mem_get_flags(uint32 address)
+void _sal_mem_unset_allocated(uint32 address)
{
- /* Get FLAG bits currently set on a specified address (byte). These may be
- queried by using a bitwise 'and' operator against the returned byte.
+ /* Unset allocated flag on a given address.
*/
assert(g_is_init);
assert(sal_mem_is_address_valid(address));
- return g_memory[address] & ~INSTRUCTION_MASK;
+
+ if (sal_mem_is_allocated(address)) {
+ g_memory[address] ^= ALLOCATED_FLAG;
+ g_allocated--;
+ }
}
uint8 sal_mem_get_inst(uint32 address)
{
- /* Get instruction currently set on a specified address (byte), with the
- FLAG bits turned off.
+ /* Get instruction currently set on a specified address, with the allocated
+ bit flag turned off.
*/
assert(g_is_init);
assert(sal_mem_is_address_valid(address));
@@ -242,21 +210,24 @@ void sal_mem_render_image(
#pragma omp parallel for
for (i = 0; i < buff_size; i++) {
uint32 j;
- uint32 flag_sum = 0;
uint32 inst_sum = 0;
+ uint32 alloc_found = 0;
uint32 cell_addr = origin + (i * cell_size);
for (j = 0; j < cell_size; j++) {
uint32 address = j + cell_addr;
if (sal_mem_is_address_valid(address)) {
- flag_sum |= sal_mem_get_flags(address);
inst_sum += sal_mem_get_inst(address);
+
+ if (sal_mem_is_allocated(address)) {
+ alloc_found = ALLOCATED_FLAG;
+ }
}
}
buffer[i] = (uint8)(inst_sum / cell_size);
- buffer[i] |= (uint8)(flag_sum);
+ buffer[i] |= (uint8)(alloc_found);
}
}
@@ -284,8 +255,7 @@ static boolean module_is_valid(void)
to when running optimized, but it is also **very** useful for debugging!
*/
uint32 bidx;
- uint32 block_start_count = 0;
- uint32 allocated_count = 0;
+ uint32 allocated = 0;
assert(g_is_init);
assert(g_capacity <= g_size / 2);
assert(inst_count_is_correct());
@@ -294,12 +264,12 @@ static boolean module_is_valid(void)
then compare the sum to the flag counters to assert module validity.
*/
for (bidx = 0; bidx < g_size; bidx++) {
- if (sal_mem_is_block_start(bidx)) block_start_count++;
- if (sal_mem_is_allocated(bidx)) allocated_count++;
+ if (sal_mem_is_allocated(bidx)) {
+ allocated++;
+ }
}
- assert(block_start_count == g_block_start_count);
- assert(allocated_count == g_allocated_count);
+ assert(allocated == g_allocated);
return TRUE;
}
diff --git a/src/process.c b/src/process.c
index 50ca3eb..5b46348 100644
--- a/src/process.c
+++ b/src/process.c
@@ -146,10 +146,6 @@ static boolean block_is_free_and_valid(uint32 address, uint32 size)
uint32 off_addr = offset + address;
if (!sal_mem_is_address_valid(off_addr)) return FALSE;
if (sal_mem_is_allocated(off_addr)) return FALSE;
-
- /* Deallocated addresses must have the BLOCK_START flag unset as well.
- */
- assert(!sal_mem_is_block_start(off_addr));
}
return TRUE;
@@ -263,7 +259,6 @@ static void proc_create(
if (allocate) {
uint32 offset;
assert(block_is_free_and_valid(address, size));
- _sal_mem_set_block_start(address);
for (offset = 0; offset < size; offset++) {
uint32 off_addr = offset + address;
@@ -293,22 +288,18 @@ void sal_proc_create(uint32 address, uint32 mb1s)
static void free_memory_block(uint32 address, uint32 size)
{
- /* Deallocate a memory block. This includes unsetting the BLOCK_START flag
- on the first byte.
+ /* Deallocate a memory block.
*/
uint32 offset;
assert(sal_mem_is_address_valid(address));
assert(sal_mem_is_address_valid(address + size - 1));
- assert(sal_mem_is_block_start(address));
assert(size);
- _sal_mem_unset_block_start(address);
for (offset = 0; offset < size; offset++) {
/* Iterate all addresses in block and unset the ALLOCATED flag in them.
*/
uint32 off_addr = offset + address;
assert(sal_mem_is_allocated(off_addr));
- assert(!sal_mem_is_block_start(off_addr));
_sal_mem_unset_allocated(off_addr);
}
}
@@ -386,7 +377,7 @@ static boolean block_is_allocated(uint32 address, uint32 size)
static boolean proc_is_valid(uint32 pidx)
{
/* Assert that the process with the given ID is in a valid state. This
- means that all of its owned memory must be allocated and that the proper
+ means that all of its owned memory must be allocated and that the allocated
flags are set in place. IP and SP must be located in valid addresses.
*/
assert(g_is_init);
@@ -395,11 +386,9 @@ static boolean proc_is_valid(uint32 pidx)
if (!sal_proc_is_free(pidx)) {
assert(sal_mem_is_address_valid(g_procs[pidx].ip));
assert(sal_mem_is_address_valid(g_procs[pidx].sp));
- assert(sal_mem_is_block_start(g_procs[pidx].mb1a));
assert(block_is_allocated(g_procs[pidx].mb1a, g_procs[pidx].mb1s));
if (g_procs[pidx].mb2s) {
- assert(sal_mem_is_block_start(g_procs[pidx].mb2a));
assert(block_is_allocated(g_procs[pidx].mb2a, g_procs[pidx].mb2s));
}
}
@@ -416,7 +405,6 @@ static boolean module_is_valid(void)
*/
uint32 pidx;
uint32 alloc_count = 0;
- uint32 block_count = 0;
assert(g_is_init);
/* Check that each individual process is in a valid state. We can do this
@@ -434,18 +422,15 @@ static boolean module_is_valid(void)
for (pidx = 0; pidx < g_capacity; pidx++) {
if (!sal_proc_is_free(pidx)) {
alloc_count += g_procs[pidx].mb1s;
- block_count++;
if (g_procs[pidx].mb2s) {
assert(g_procs[pidx].mb1a != g_procs[pidx].mb2a);
alloc_count += g_procs[pidx].mb2s;
- block_count++;
}
}
}
- assert(block_count == sal_mem_get_block_start_count());
- assert(alloc_count == sal_mem_get_allocated_count());
+ assert(alloc_count == sal_mem_get_allocated());
return TRUE;
}
@@ -849,17 +834,12 @@ static void alloc(uint32 pidx, boolean forward)
}
/* CONDITION 3: no collision detected; enlarge child memory block and
- increment seeker pointer. Also, correct position of BLOCK_START bit flag.
+ increment seeker pointer.
*/
_sal_mem_set_allocated(g_procs[pidx].sp);
- if (!g_procs[pidx].mb2s) {
- g_procs[pidx].mb2a = g_procs[pidx].sp;
- _sal_mem_set_block_start(g_procs[pidx].sp);
- } else if (!forward) {
- _sal_mem_unset_block_start(g_procs[pidx].mb2a);
+ if (!g_procs[pidx].mb2s || !forward) {
g_procs[pidx].mb2a = g_procs[pidx].sp;
- _sal_mem_set_block_start(g_procs[pidx].mb2a);
}
g_procs[pidx].mb2s++;
@@ -1312,7 +1292,7 @@ void _sal_proc_cycle(void)
/* Kill oldest processes whenever memory gets filled over capacity.
*/
- while (sal_mem_get_allocated_count() > sal_mem_get_capacity()) {
+ while (sal_mem_get_allocated() > sal_mem_get_capacity()) {
proc_kill();
}
}