aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bin/printer.py3
-rw-r--r--include/memory.h26
-rw-r--r--src/memory.c116
-rw-r--r--src/process.c32
4 files changed, 53 insertions, 124 deletions
diff --git a/bin/printer.py b/bin/printer.py
index e29f4f8..14aea6f 100644
--- a/bin/printer.py
+++ b/bin/printer.py
@@ -512,8 +512,7 @@ class Printer:
("MEMORY", [
("e", "order", self.__sim.lib.sal_mem_get_order),
("e", "size", self.__sim.lib.sal_mem_get_size),
- ("e", "blocks", self.__sim.lib.sal_mem_get_block_start_count),
- ("e", "allocated", self.__sim.lib.sal_mem_get_allocated_count),
+ ("e", "allocated", self.__sim.lib.sal_mem_get_allocated),
("s", ""),
("h", "INSTRUCTIONS"),
] + inst_widget),
diff --git a/include/memory.h b/include/memory.h
index 9797cd7..04284e7 100644
--- a/include/memory.h
+++ b/include/memory.h
@@ -3,14 +3,13 @@
* @author Paul Oliver
*
* This module gives access to Salis memory. You can check the state of each
-* byte (instruction and flags) at any time and also perform manual memory
+* byte (instruction and alloc-flag) at any time and also perform manual memory
* manipulations.
*/
#ifndef SALIS_MEMORY_H
#define SALIS_MEMORY_H
-#define BLOCK_START_FLAG 0x40
#define ALLOCATED_FLAG 0x20
#define INSTRUCTION_MASK 0x1f
@@ -29,15 +28,10 @@ SALIS_API uint32 sal_mem_get_order(void);
*/
SALIS_API uint32 sal_mem_get_size(void);
-/** Get amount of addresses with the memory-block-start flag set on them.
-* @return Amount of addresses with the memory-block-start flag set
-*/
-SALIS_API uint32 sal_mem_get_block_start_count(void);
-
/** Get amount of addresses with the allocated flag set on them.
* @return Amount of addresses with the allocated flag set
*/
-SALIS_API uint32 sal_mem_get_allocated_count(void);
+SALIS_API uint32 sal_mem_get_allocated(void);
/** Get memory capacity.
* @return Memory capacity (capacity == size / 2)
@@ -61,29 +55,15 @@ SALIS_API boolean sal_mem_is_over_capacity(void);
*/
SALIS_API boolean sal_mem_is_address_valid(uint32 address);
-/** Check if given address has the memory-block-start flag set.
-* @param address Address being queried
-* @return Memory-block-start flag is set on this address
-*/
-SALIS_API boolean sal_mem_is_block_start(uint32 address);
-
/** Check if given address has the allocated flag set.
* @param address Address being queried
* @return Allocated flag is set on this address
*/
SALIS_API boolean sal_mem_is_allocated(uint32 address);
-void _sal_mem_set_block_start(uint32 address);
void _sal_mem_set_allocated(uint32 address);
-void _sal_mem_unset_block_start(uint32 address);
void _sal_mem_unset_allocated(uint32 address);
-/** Get currently set flags at given address.
-* @param address Address being queried
-* @return Byte containing set flag bits
-*/
-SALIS_API uint8 sal_mem_get_flags(uint32 address);
-
/** Get current instruction at address.
* @param address Address being queried
* @return Instruction currently written at address
@@ -98,7 +78,7 @@ SALIS_API void sal_mem_set_inst(uint32 address, uint8 inst);
/** Get current byte at address.
* @param address Address being queried
-* @return Byte currently written at address (includes bit flags & instruction)
+* @return Byte currently written at address (includes alloc-flag & instruction)
*/
SALIS_API uint8 sal_mem_get_byte(uint32 address);
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();
}
}