aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bin/modules/handler.py2
-rw-r--r--bin/modules/printer.py3
-rwxr-xr-xbin/salis.py5
-rw-r--r--include/common.h17
-rw-r--r--include/evolver.h23
-rw-r--r--include/instset.h12
-rw-r--r--include/memory.h52
-rw-r--r--include/process.h44
-rw-r--r--include/render.h8
-rw-r--r--include/salis.h24
-rw-r--r--src/common.c22
-rw-r--r--src/evolver.c44
-rw-r--r--src/instset.c18
-rw-r--r--src/memory.c80
-rw-r--r--src/process.c479
-rw-r--r--src/render.c53
-rw-r--r--src/salis.c42
17 files changed, 564 insertions, 364 deletions
diff --git a/bin/modules/handler.py b/bin/modules/handler.py
index ba2b249..ad62c5c 100644
--- a/bin/modules/handler.py
+++ b/bin/modules/handler.py
@@ -1,6 +1,6 @@
""" SALIS: Viewer/controller for the SALIS simulator.
-file: handler.py
+File: handler.py
Author: Paul Oliver
Email: paul.t.oliver.design@gmail.com
diff --git a/bin/modules/printer.py b/bin/modules/printer.py
index cfbca84..bf664d2 100644
--- a/bin/modules/printer.py
+++ b/bin/modules/printer.py
@@ -12,9 +12,10 @@ format. It makes use of the curses library for terminal handling.
import curses
import curses.textpad
import os
-
from collections import OrderedDict
+
from ctypes import c_uint32, cast, POINTER
+
from modules.world import World
diff --git a/bin/salis.py b/bin/salis.py
index f51484c..e40e72d 100755
--- a/bin/salis.py
+++ b/bin/salis.py
@@ -20,13 +20,14 @@ import os
import re
import sys
import time
-
from argparse import ArgumentParser, HelpFormatter
+from subprocess import check_call
+
from ctypes import CDLL, c_bool, c_uint8, c_uint32, c_char_p, POINTER
+
from modules.common import Common
from modules.handler import Handler
from modules.printer import Printer
-from subprocess import check_call
__version__ = "2.0"
diff --git a/include/common.h b/include/common.h
index 50ac563..2db1258 100644
--- a/include/common.h
+++ b/include/common.h
@@ -12,24 +12,33 @@
#ifndef SALIS_COMMON_H
#define SALIS_COMMON_H
-/* Typedef sender functor type for easy python parsing.
+/**
+* Typedef sender functor type for easy python parsing.
*/
typedef void (*Sender)(uint8 inst);
-/* Typedef receiver functor type for easy python parsing.
+/**
+* Typedef receiver functor type for easy python parsing.
*/
typedef uint8 (*Receiver)(void);
-/* Set sender functor. When unset, SEND instruction does nothing.
+/**
+* Set sender functor. When unset, SEND instruction does nothing.
* @param sender Sender functor
*/
SALIS_API void sal_comm_set_sender(Sender sender);
-/* Set receiver functor. When unset, RCVE instruction does nothing.
+/**
+* Set receiver functor. When unset, RCVE instruction does nothing.
* @param receiver Receiver functor
*/
SALIS_API void sal_comm_set_receiver(Receiver receiver);
+
+/*******************************
+* PRIVATES *
+*******************************/
+
void _sal_comm_send(uint8 inst);
uint8 _sal_comm_receive(void);
diff --git a/include/evolver.h b/include/evolver.h
index 457cd9a..26c7d6a 100644
--- a/include/evolver.h
+++ b/include/evolver.h
@@ -10,27 +10,34 @@
#ifndef SALIS_EVOLVER_H
#define SALIS_EVOLVER_H
-void _sal_evo_init(void);
-void _sal_evo_quit(void);
-void _sal_evo_load_from(FILE *file);
-void _sal_evo_save_into(FILE *file);
-
-/** Get address where the last cosmic ray landed.
+/**
+* Get address where the last cosmic ray landed.
* @return Last address changed by a cosmic ray
*/
SALIS_API uint32 sal_evo_get_last_changed_address(void);
-/** Get amount of random numbers generated during the last simulation cycle.
+/**
+* Get amount of random numbers generated during the last simulation cycle.
* @return Number of calls to the random number generator during the last cycle
*/
SALIS_API uint32 sal_evo_get_calls_on_last_cycle(void);
-/** Access the internal state of the XOR-Shift random number generator.
+/**
+* Access the internal state of the XOR-Shift random number generator.
* @param state_index Index of one of the 32 bit state-blocks [0-4]
* @return State of the 32 bit block
*/
SALIS_API uint32 sal_evo_get_state(uint8 state_index);
+
+/*******************************
+* PRIVATES *
+*******************************/
+
+void _sal_evo_init(void);
+void _sal_evo_quit(void);
+void _sal_evo_load_from(FILE *file);
+void _sal_evo_save_into(FILE *file);
void _sal_evo_randomize_at(uint32 address);
void _sal_evo_cycle(void);
diff --git a/include/instset.h b/include/instset.h
index a7f4773..cde1498 100644
--- a/include/instset.h
+++ b/include/instset.h
@@ -12,7 +12,8 @@
#define INST_COUNT 32
-/** Salis instruction set. The 'SALIS_INST' macro and inline doc-comments help
+/**
+* Salis instruction set. The 'SALIS_INST' macro and inline doc-comments help
* python parse this file. Don't edit these unless you know what you're doing!
*/
enum {
@@ -50,19 +51,22 @@ enum {
SALIS_INST POPN /**< ~ Pop value from stack */
};
-/** Determine if an unsigned integer contains a valid instruction.
+/**
+* Determine if an unsigned integer contains a valid instruction.
* @param byte Any unsigned integer up to 32 bits
* @return Whether or nor integer contains a valid instruction
*/
SALIS_API boolean sal_is_inst(uint32 word);
-/** Determine if instruction is a template constructor [NOP0-NOP1].
+/**
+* Determine if instruction is a template constructor [NOP0-NOP1].
* @param inst Must contain a valid instruction
* @return Whether or not instruction is a template constructor
*/
SALIS_API boolean sal_is_template(uint32 inst);
-/** Determine if instruction a register modifier [MOD0-MOD3].
+/**
+* Determine if instruction a register modifier [MOD0-MOD3].
* @param inst Must contain a valid instruction
* @return Whether or not instruction is a register modifier
*/
diff --git a/include/memory.h b/include/memory.h
index 6376d7c..e144228 100644
--- a/include/memory.h
+++ b/include/memory.h
@@ -13,75 +13,89 @@
#define ALLOCATED_FLAG 0x20
#define INSTRUCTION_MASK 0x1f
-void _sal_mem_init(uint32 order);
-void _sal_mem_quit(void);
-void _sal_mem_load_from(FILE *file);
-void _sal_mem_save_into(FILE *file);
-
-/** Get memory order.
+/**
+* Get memory order.
* @return Order of memory (memory_size == 1 << order)
*/
SALIS_API uint32 sal_mem_get_order(void);
-/** Get memory size.
+/**
+* Get memory size.
* @return Size of memory (memory_size == 1 << order)
*/
SALIS_API uint32 sal_mem_get_size(void);
-/** Get amount of addresses with the allocated flag set on them.
+/**
+* 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(void);
-/** Get memory capacity.
+/**
+* Get memory capacity.
* @return Memory capacity (capacity == size / 2)
*/
SALIS_API uint32 sal_mem_get_capacity(void);
-/** Get amount of addresses with a given instruction written on them.
+/**
+* Get amount of addresses with a given instruction written on them.
* @param inst Instruction whose amount we want to count
* @return Amount of addresses with given instruction
*/
SALIS_API uint32 sal_mem_get_inst_count(uint8 inst);
-/** Determine if memory is above its capacity.
+/**
+* Determine if memory is above its capacity.
* @return Memory is above capacity
*/
SALIS_API boolean sal_mem_is_over_capacity(void);
-/** Check validity of address.
+/**
+* Check validity of address.
* @param address Address being queried
* @return Validity of address (validity == address < size)
*/
SALIS_API boolean sal_mem_is_address_valid(uint32 address);
-/** Check if given address has the allocated flag set.
+/**
+* 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_allocated(uint32 address);
-void _sal_mem_unset_allocated(uint32 address);
-
-/** Get current instruction at address.
+/**
+* Get current instruction at address.
* @param address Address being queried
* @return Instruction currently written at address
*/
SALIS_API uint8 sal_mem_get_inst(uint32 address);
-/** Write instruction into address.
+/**
+* Write instruction into address.
* @param address Address being set
* @param inst Instruction to write at given address
*/
SALIS_API void sal_mem_set_inst(uint32 address, uint8 inst);
-/** Get current byte at address.
+/**
+* Get current byte at address.
* @param address Address being queried
* @return Byte currently written at address (includes alloc-flag & instruction)
*/
SALIS_API uint8 sal_mem_get_byte(uint32 address);
+
+/*******************************
+* PRIVATES *
+*******************************/
+
+void _sal_mem_init(uint32 order);
+void _sal_mem_quit(void);
+void _sal_mem_load_from(FILE *file);
+void _sal_mem_save_into(FILE *file);
+void _sal_mem_set_allocated(uint32 address);
+void _sal_mem_unset_allocated(uint32 address);
void _sal_mem_cycle(void);
#endif
diff --git a/include/process.h b/include/process.h
index 26772c3..aa017c6 100644
--- a/include/process.h
+++ b/include/process.h
@@ -11,7 +11,8 @@
#ifndef SALIS_PROCESS_H
#define SALIS_PROCESS_H
-/** The Process data-structure. The 'SALIS_PROC_ELEMENT' macro helps python
+/**
+* The Process data-structure. The 'SALIS_PROC_ELEMENT' macro helps python
* parse the struct, so don't change it!
*/
struct Process
@@ -31,59 +32,72 @@ struct Process
typedef struct Process Process;
-void _sal_proc_init(void);
-void _sal_proc_quit(void);
-void _sal_proc_load_from(FILE *file);
-void _sal_proc_save_into(FILE *file);
-
-/** Get process count.
+/**
+* Get process count.
* @return Amount of running (living) processes
*/
SALIS_API uint32 sal_proc_get_count(void);
-/** Get reaper queue capacity.
+/**
+* Get reaper queue capacity.
* @return Currently allocated size of reaper queue
*/
SALIS_API uint32 sal_proc_get_capacity(void);
-/** Get first process.
+/**
+* Get first process.
* @return Process currently on top of reaper queue
*/
SALIS_API uint32 sal_proc_get_first(void);
-/** Get last process.
+/**
+* Get last process.
* @return Process currently on bottom of reaper queue (closest to death)
*/
SALIS_API uint32 sal_proc_get_last(void);
-/** Check if process is currently free.
+/**
+* Check if process is currently free.
* @param proc_id ID of process whose status we want to check
* @return Status (either free or running) of the process with the given ID
*/
SALIS_API boolean sal_proc_is_free(uint32 proc_id);
-/** Get process.
+/**
+* Get process.
* @param proc_id ID of Process being queried
* @return A copy of the process with the given ID
*/
SALIS_API Process sal_proc_get_proc(uint32 proc_id);
-/** Get process data.
+/**
+* Get process data.
* @param proc_id ID of Process being queried
* @param buffer Pre-allocated buffer to store data on [ > sizeof(Process)]
*/
SALIS_API void sal_proc_get_proc_data(uint32 proc_id, uint32_p buffer);
-/** Create new process.
+/**
+* Create new process.
* @param address Address we want to allocate our process into
* @param mb1_size Size of the memory block we want to allocate for our process
*/
SALIS_API void sal_proc_create(uint32 address, uint32 mb1_size);
-/** Kill process on bottom of reaper queue.
+/**
+* Kill process on bottom of reaper queue.
*/
SALIS_API void sal_proc_kill(void);
+
+/*******************************
+* PRIVATES *
+*******************************/
+
+void _sal_proc_init(void);
+void _sal_proc_quit(void);
+void _sal_proc_load_from(FILE *file);
+void _sal_proc_save_into(FILE *file);
void _sal_proc_cycle(void);
#endif
diff --git a/include/render.h b/include/render.h
index b48fb8f..9a659c4 100644
--- a/include/render.h
+++ b/include/render.h
@@ -10,7 +10,8 @@
#ifndef SALIS_RENDER_H
#define SALIS_RENDER_H
-/** Render a 1D image of a given block of memory. This is useful, as rendering
+/**
+* Render a 1D image of a given block of memory. This is useful, as rendering
* directly in python would be too slow. We use openmp for multi-threaded image
* generation.
*
@@ -19,7 +20,8 @@
* @param buff_size Amount of pixels (cells) to be generated
* @param buffer Pre-allocated buffer to store the rendered pixels into
*/
-SALIS_API void sal_ren_get_image(uint32 origin, uint32 cell_size,
- uint32 buff_size, uint8_p buffer);
+SALIS_API void sal_ren_get_image(
+ uint32 origin, uint32 cell_size, uint32 buff_size, uint8_p buffer
+);
#endif
diff --git a/include/salis.h b/include/salis.h
index 75ef9dd..4394cdb 100644
--- a/include/salis.h
+++ b/include/salis.h
@@ -20,41 +20,49 @@
#include <common.h>
#include <process.h>
-/** Initialize Salis simulation.
+/**
+* Initialize Salis simulation.
* @param order Order of memory (memory_size == 1 << order)
*/
SALIS_API void sal_main_init(uint32 order);
-/** Free resources and quit Salis.
+/**
+* Free resources and quit Salis.
*/
SALIS_API void sal_main_quit(void);
-/** Load existing Salis simulation from saved file.
+/**
+* Load existing Salis simulation from saved file.
* @param file_name Path of the save file to be loaded
*/
SALIS_API void sal_main_load(string file_name);
-/** Save Salis simulation to a file.
+/**
+* Save Salis simulation to a file.
* @param file_name Path of the save file to be created
*/
SALIS_API void sal_main_save(string file_name);
-/** Check if Salis simulation has been correctly initialized.
+/**
+* Check if Salis simulation has been correctly initialized.
* @return Salis has been correctly initialized
*/
SALIS_API boolean sal_main_is_init(void);
-/** Get current simulation cycle.
+/**
+* Get current simulation cycle.
* @return Current simulation cycle
*/
SALIS_API uint32 sal_main_get_cycle(void);
-/** Get current simulation epoch.
+/**
+* Get current simulation epoch.
* @return Current simulation epoch (1 epoch == 2^32 cycles)
*/
SALIS_API uint32 sal_main_get_epoch(void);
-/** Update simulation once. This will cycle all Salis modules and processes.
+/**
+* Update simulation once. This will cycle all Salis modules and processes.
*/
SALIS_API void sal_main_cycle(void);
diff --git a/src/common.c b/src/common.c
index 402320e..a2fc559 100644
--- a/src/common.c
+++ b/src/common.c
@@ -8,8 +8,9 @@ static Receiver g_receiver;
void sal_comm_set_sender(Sender sender)
{
- /* Set sender functor. Whenever an organism calls the SEND instruction,
- this function will get called. When unset, SEND instruction is ignored.
+ /*
+ * Set sender functor. Whenever an organism calls the SEND instruction,
+ * this function will get called. When unset, SEND instruction is ignored.
*/
assert(sender);
g_sender = sender;
@@ -17,8 +18,9 @@ void sal_comm_set_sender(Sender sender)
void sal_comm_set_receiver(Receiver receiver)
{
- /* Set receiver functor. Whenever an organism calls the RCVE instruction,
- this function will get called. When unset, RCVE instruction is ignored.
+ /*
+ * Set receiver functor. Whenever an organism calls the RCVE instruction,
+ * this function will get called. When unset, RCVE instruction is ignored.
*/
assert(receiver);
g_receiver = receiver;
@@ -26,8 +28,9 @@ void sal_comm_set_receiver(Receiver receiver)
void _sal_comm_send(uint8 inst)
{
- /* Send a single byte (instruction) to the sender. This function is called
- by processes that execute the SEND instruction.
+ /*
+ * Send a single byte (instruction) to the sender. This function is called
+ * by processes that execute the SEND instruction.
*/
assert(sal_is_inst(inst));
@@ -38,9 +41,10 @@ void _sal_comm_send(uint8 inst)
uint8 _sal_comm_receive(void)
{
- /* Receive a single byte (instruction) from the receiver. This function is
- called by processes that execute the RCVE instruction. It returns NOP0 is
- receiver is unset.
+ /*
+ * Receive a single byte (instruction) from the receiver. This function is
+ * called by processes that execute the RCVE instruction. It returns NOP0 is
+ * receiver is unset.
*/
if (g_receiver) {
uint8 inst = g_receiver();
diff --git a/src/evolver.c b/src/evolver.c
index e3b6ef7..dfba958 100644
--- a/src/evolver.c
+++ b/src/evolver.c
@@ -16,8 +16,9 @@ static uint32 g_state[4];
void _sal_evo_init(void)
{
- /* Start up the evolver module. We simply set the 128 bits into a random
- state by calling 'rand()'.
+ /*
+ * Start up the evolver module. We simply set the 128 bits into a random
+ * state by calling 'rand()'.
*/
assert(!g_is_init);
srand((uint32)time(NULL));
@@ -30,7 +31,8 @@ void _sal_evo_init(void)
void _sal_evo_quit(void)
{
- /* Quit the evolver module. Reset everything back to zero.
+ /*
+ * Quit the evolver module. Reset everything back to zero.
*/
assert(g_is_init);
g_is_init = FALSE;
@@ -41,7 +43,8 @@ void _sal_evo_quit(void)
void _sal_evo_load_from(FILE *file)
{
- /* Load evolver state from a binary file.
+ /*
+ * Load evolver state from a binary file.
*/
assert(!g_is_init);
assert(file);
@@ -53,7 +56,8 @@ void _sal_evo_load_from(FILE *file)
void _sal_evo_save_into(FILE *file)
{
- /* Save evolver state into a binary file.
+ /*
+ * Save evolver state into a binary file.
*/
assert(g_is_init);
assert(file);
@@ -63,15 +67,17 @@ void _sal_evo_save_into(FILE *file)
fwrite(&g_state, sizeof(uint32), 4, file);
}
-/* Getter methods for the evolver module.
+/*
+* Getter methods for the evolver module.
*/
UINT32_GETTER(evo, last_changed_address)
UINT32_GETTER(evo, calls_on_last_cycle)
uint32 sal_evo_get_state(uint8 state_index)
{
- /* Get part of the evolver's internal state (32 bits of 128 total bits) as
- an unsigned int.
+ /*
+ * Get part of the evolver's internal state (32 bits of 128 total bits) as
+ * an unsigned int.
*/
assert(g_is_init);
assert(state_index < 4);
@@ -80,10 +86,11 @@ uint32 sal_evo_get_state(uint8 state_index)
static uint32 generate_random_number(void)
{
- /* Generate a single 32 bit random number. This module makes use of the
- XOR-Shift pseudo-rng. We use XOR-Shift because it's extremely lightweight
- and fast, while providing quite good results. Find more info about it here:
- >>> https://en.wikipedia.org/wiki/Xorshift
+ /*
+ * Generate a single 32 bit random number. This module makes use of the
+ * XOR-Shift pseudo-rng. We use XOR-Shift because it's extremely lightweight
+ * and fast, while providing quite good results. Find more info about it at:
+ * https://en.wikipedia.org/wiki/Xorshift
*/
uint32 tmp1;
uint32 tmp2;
@@ -103,7 +110,8 @@ static uint32 generate_random_number(void)
void _sal_evo_randomize_at(uint32 address)
{
- /* Place a random instruction into a given address.
+ /*
+ * Place a random instruction into a given address.
*/
uint8 inst;
assert(g_is_init);
@@ -115,11 +123,11 @@ void _sal_evo_randomize_at(uint32 address)
void _sal_evo_cycle(void)
{
- /* During each simulation cycle, a random 32 bit integer is generated. If
- this integer represents a 'valid' address in memory
- (i.e. new_rand < memory_size), this address becomes hit by a cosmic ray
- (randomized). This simple mutation scheme is enough to drive evolution in
- Salis.
+ /*
+ * During each simulation cycle, a random 32 bit integer is generated. If
+ * this integer represents a 'valid' address in memory (new_rand < mem_size),
+ * this address becomes hit by a cosmic ray (randomized). This simple
+ * mutation scheme is enough to drive evolution in Salis.
*/
uint32 address;
assert(g_is_init);
diff --git a/src/instset.c b/src/instset.c
index 2ab127a..94c3df7 100644
--- a/src/instset.c
+++ b/src/instset.c
@@ -4,15 +4,17 @@
boolean sal_is_inst(uint32 word)
{
- /* Test if a given 32 bit integer contains a valid Salis instruction.
+ /*
+ * Test if a given 32 bit integer contains a valid Salis instruction.
*/
return word < INST_COUNT;
}
static boolean is_in_between(uint32 inst, uint32 low, uint32 hi)
{
- /* Test whether a Salis instruction lies within a given range. This is
- useful for identifying template instructions and/or register modifiers.
+ /*
+ * Test whether a Salis instruction lies within a given range. This is
+ * useful for identifying template instructions and/or register modifiers.
*/
assert(sal_is_inst(inst));
assert(sal_is_inst(low));
@@ -22,8 +24,9 @@ static boolean is_in_between(uint32 inst, uint32 low, uint32 hi)
boolean sal_is_template(uint32 inst)
{
- /* Test whether a given instruction is a template element
- (i.e. NOP0 or NOP1).
+ /*
+ * Test whether a given instruction is a template element (i.e. NOP0 or
+ * NOP1).
*/
assert(sal_is_inst(inst));
return is_in_between(inst, NOP0, NOP1);
@@ -31,8 +34,9 @@ boolean sal_is_template(uint32 inst)
boolean sal_is_mod(uint32 inst)
{
- /* Test whether a given instruction is a register modifier
- (i.e. MODA, MODB, MODC or MODD).
+ /*
+ * Test whether a given instruction is a register modifier (i.e. MODA, MODB,
+ * MODC or MODD).
*/
assert(sal_is_inst(inst));
return is_in_between(inst, MODA, MODD);
diff --git a/src/memory.c b/src/memory.c
index b02a5b9..7f51df4 100644
--- a/src/memory.c
+++ b/src/memory.c
@@ -17,9 +17,10 @@ static uint8_p g_memory;
void _sal_mem_init(uint32 order)
{
- /* Set memory module to its initial state. We calculate memory size based
- on its order (size = 1 << order) and allocate an array of such size. We
- also initialize the array completely to zero.
+ /*
+ * Set memory module to its initial state. We calculate memory size based
+ * on its order (size = 1 << order) and allocate an array of such size. We
+ * also initialize the array completely to zero.
*/
assert(!g_is_init);
assert(order < 32);
@@ -34,8 +35,9 @@ void _sal_mem_init(uint32 order)
void _sal_mem_quit(void)
{
- /* Reset memory module entirely back to zero. That way, we can load several
- simulations without restarting the application entirely.
+ /*
+ * Reset memory module entirely back to zero. That way, we can load several
+ * simulations without restarting the application entirely.
*/
assert(g_is_init);
free(g_memory);
@@ -50,7 +52,8 @@ void _sal_mem_quit(void)
void _sal_mem_load_from(FILE *file)
{
- /* Load memory state from a binary file.
+ /*
+ * Load memory state from a binary file.
*/
assert(!g_is_init);
assert(file);
@@ -67,7 +70,8 @@ void _sal_mem_load_from(FILE *file)
void _sal_mem_save_into(FILE *file)
{
- /* Save memory state to a binary file.
+ /*
+ * Save memory state to a binary file.
*/
assert(g_is_init);
assert(file);
@@ -80,7 +84,8 @@ void _sal_mem_save_into(FILE *file)
fwrite(g_memory, sizeof(uint8), g_size, file);
}
-/* Getter methods for the memory module.
+/*
+* Getter methods for the memory module.
*/
UINT32_GETTER(mem, order)
UINT32_GETTER(mem, size)
@@ -89,8 +94,9 @@ UINT32_GETTER(mem, capacity)
uint32 sal_mem_get_inst_count(uint8 inst)
{
- /* Return number of times a certain instruction appears in memory. The
- instruction counter gets updated dynamically during each cycle.
+ /*
+ * Return number of times a certain instruction appears in memory. The
+ * instruction counter gets updated dynamically during each cycle.
*/
assert(g_is_init);
assert(sal_is_inst(inst));
@@ -99,8 +105,9 @@ uint32 sal_mem_get_inst_count(uint8 inst)
boolean sal_mem_is_over_capacity(void)
{
- /* Check if memory is filled above 50%. If so, old organisms will be popped
- out of the reaper queue!
+ /*
+ * Check if memory is filled above 50%. If so, old organisms will be popped
+ * out of the reaper queue!
*/
assert(g_is_init);
return g_allocated > g_capacity;
@@ -108,7 +115,8 @@ boolean sal_mem_is_over_capacity(void)
boolean sal_mem_is_address_valid(uint32 address)
{
- /* Check if given address is valid.
+ /*
+ * Check if given address is valid.
*/
assert(g_is_init);
return address < g_size;
@@ -116,7 +124,8 @@ boolean sal_mem_is_address_valid(uint32 address)
boolean sal_mem_is_allocated(uint32 address)
{
- /* Check if given address is allocated.
+ /*
+ * Check if given address is allocated.
*/
assert(g_is_init);
assert(sal_mem_is_address_valid(address));
@@ -125,7 +134,8 @@ boolean sal_mem_is_allocated(uint32 address)
void _sal_mem_set_allocated(uint32 address)
{
- /* Set allocated flag on a given address.
+ /*
+ * Set allocated flag on a given address.
*/
assert(g_is_init);
assert(sal_mem_is_address_valid(address));
@@ -138,7 +148,8 @@ void _sal_mem_set_allocated(uint32 address)
void _sal_mem_unset_allocated(uint32 address)
{
- /* Unset allocated flag on a given address.
+ /*
+ * Unset allocated flag on a given address.
*/
assert(g_is_init);
assert(sal_mem_is_address_valid(address));
@@ -151,8 +162,9 @@ void _sal_mem_unset_allocated(uint32 address)
uint8 sal_mem_get_inst(uint32 address)
{
- /* Get instruction currently set on a specified address, with the allocated
- bit flag 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));
@@ -161,8 +173,9 @@ uint8 sal_mem_get_inst(uint32 address)
void sal_mem_set_inst(uint32 address, uint8 inst)
{
- /* Set instruction at given address. This is useful when performing manual
- memory manipulations (like compiling organism genomes).
+ /*
+ * Set instruction at given address. This is useful when performing manual
+ * memory manipulations (like compiling organism genomes).
*/
assert(g_is_init);
assert(sal_mem_is_address_valid(address));
@@ -175,8 +188,9 @@ void sal_mem_set_inst(uint32 address, uint8 inst)
uint8 sal_mem_get_byte(uint32 address)
{
- /* Get unadulterated byte at given address. This could be used, for
- example, to render nice images of the memory state.
+ /*
+ * Get unadulterated byte at given address. This could be used, for example,
+ * to render nice images of the memory state.
*/
assert(g_is_init);
assert(sal_mem_is_address_valid(address));
@@ -185,8 +199,9 @@ uint8 sal_mem_get_byte(uint32 address)
static boolean inst_count_is_correct(void)
{
- /* Check that the instruction counter is in a valid state
- (i.e. SUM inst_counter[0..(INST_COUNT - 1)] == memory_size).
+ /*
+ * Check that the instruction counter is in a valid state (i.e.
+ * SUM inst_counter[0..(INST_COUNT - 1)] == memory_size).
*/
uint32 i;
uint32 sum = 0;
@@ -202,9 +217,10 @@ static boolean inst_count_is_correct(void)
static boolean module_is_valid(void)
{
- /* Check for validity of memory module. This function only gets called when
- Salis is running in debug mode. It makes Salis **very** slow in comparison
- to when running optimized, but it is also **very** useful for debugging!
+ /*
+ * Check for validity of memory module. This function only gets called when
+ * Salis is running in debug mode. It makes Salis **very** slow in comparison
+ * to when running optimized, but it is also **very** useful for debugging!
*/
uint32 bidx;
uint32 allocated = 0;
@@ -212,8 +228,9 @@ static boolean module_is_valid(void)
assert(g_capacity <= g_size / 2);
assert(inst_count_is_correct());
- /* Iterate through all memory, counting the flags set on each address. We
- then compare the sum to the flag counters to assert module validity.
+ /*
+ * Iterate through all memory, counting the flags set on each address. We
+ * then compare the sum to the flag counters to assert module validity.
*/
for (bidx = 0; bidx < g_size; bidx++) {
if (sal_mem_is_allocated(bidx)) {
@@ -227,8 +244,9 @@ static boolean module_is_valid(void)
void _sal_mem_cycle(void)
{
- /* Cycle memory module. Simply assert validity when running in debug mode.
- When running optimized, this function does nothing.
+ /*
+ * Cycle memory module. Simply assert validity when running in debug mode.
+ * When running optimized, this function does nothing.
*/
assert(g_is_init);
assert(module_is_valid());
diff --git a/src/process.c b/src/process.c
index eb89a8d..3a674c1 100644
--- a/src/process.c
+++ b/src/process.c
@@ -19,10 +19,11 @@ static Process *g_procs;
void _sal_proc_init(void)
{
- /* Initialize process module to its initial state. We initialize the reaper
- queue with a capacity of 1. 'First' and 'last' organism pointers are
- initialized to (uint32)-1 (to indicate they point to no organism, as no
- organism exists yet).
+ /*
+ * Initialize process module to its initial state. We initialize the reaper
+ * queue with a capacity of 1. 'First' and 'last' organism pointers are
+ * initialized to (uint32)-1 (to indicate they point to no organism, as no
+ * organism exists yet).
*/
assert(!g_is_init);
g_is_init = TRUE;
@@ -35,7 +36,8 @@ void _sal_proc_init(void)
void _sal_proc_quit(void)
{
- /* Reset process module back to zero; free up the process queue.
+ /*
+ * Reset process module back to zero; free up the process queue.
*/
assert(g_is_init);
free(g_procs);
@@ -49,7 +51,8 @@ void _sal_proc_quit(void)
void _sal_proc_load_from(FILE *file)
{
- /* Load process module state from a binary file.
+ /*
+ * Load process module state from a binary file.
*/
assert(!g_is_init);
assert(file);
@@ -65,7 +68,8 @@ void _sal_proc_load_from(FILE *file)
void _sal_proc_save_into(FILE *file)
{
- /* Save process module state to a binary file.
+ /*
+ * Save process module state to a binary file.
*/
assert(g_is_init);
assert(file);
@@ -77,7 +81,8 @@ void _sal_proc_save_into(FILE *file)
fwrite(g_procs, sizeof(Process), g_capacity, file);
}
-/* Getter methods for the process module.
+/*
+* Getter methods for the process module.
*/
UINT32_GETTER(proc, count)
UINT32_GETTER(proc, capacity)
@@ -86,18 +91,20 @@ UINT32_GETTER(proc, last)
boolean sal_proc_is_free(uint32 proc_id)
{
- /* In Salis, the reaper queue is implemented as a circular queue. Thus, at
- any given time, a process ID (which actually denotes a process 'address'
- or, more correctly, a process 'container address') might contain a living
- process or be empty. This function checks for the 'living' state of a given
- process ID.
+ /*
+ * In Salis, the reaper queue is implemented as a circular queue. Thus, at
+ * any given time, a process ID (which actually denotes a process 'address'
+ * or, more correctly, a process 'container address') might contain a living
+ * process or be empty. This function checks for the 'living' state of a
+ * given process ID.
*/
assert(g_is_init);
assert(proc_id < g_capacity);
if (!g_procs[proc_id].mb1s) {
- /* When running in debug mode, we make sure that non-living processes
- are completely set to zero, as this is the expected state.
+ /*
+ * When running in debug mode, we make sure that non-living processes
+ * are completely set to zero, as this is the expected state.
*/
#ifndef NDEBUG
Process dummy_proc;
@@ -113,8 +120,9 @@ boolean sal_proc_is_free(uint32 proc_id)
Process sal_proc_get_proc(uint32 proc_id)
{
- /* Get a **copy** (not a reference) of the process with the given ID. Note,
- this might be a non-living process.
+ /*
+ * Get a **copy** (not a reference) of the process with the given ID. Note,
+ * this might be a non-living process.
*/
assert(g_is_init);
assert(proc_id < g_capacity);
@@ -123,11 +131,12 @@ Process sal_proc_get_proc(uint32 proc_id)
void sal_proc_get_proc_data(uint32 proc_id, uint32_p buffer)
{
- /* Get a **copy** (not a reference) of the process with the given ID
- (represented as a string of 32 bit integers) written into the given buffer.
- The buffer must be pre-allocated to a large enough size
- (i.e. malloc(sizeof(Process))). Note, copied process might be in a
- non-living state.
+ /*
+ * Get a **copy** (not a reference) of the process with the given ID
+ * (represented as a string of 32 bit integers) written into the given
+ * buffer. The buffer must be pre-allocated to a large enough size (i.e.
+ * malloc(sizeof(Process))). Note, copied process might be in a non-living
+ * state.
*/
assert(g_is_init);
assert(proc_id < g_capacity);
@@ -137,8 +146,9 @@ void sal_proc_get_proc_data(uint32 proc_id, uint32_p buffer)
static boolean block_is_free_and_valid(uint32 address, uint32 size)
{
- /* Iterate all addresses in the given memory block and check that they lie
- within memory bounds and have the ALLOCATED flag unset.
+ /*
+ * Iterate all addresses in the given memory block and check that they lie
+ * within memory bounds and have the ALLOCATED flag unset.
*/
uint32 offset;
@@ -153,13 +163,14 @@ static boolean block_is_free_and_valid(uint32 address, uint32 size)
static void realloc_queue(uint32 queue_lock)
{
- /* Reallocate reaper queue into a new circular queue with double the
- capacity. This function gets called whenever the reaper queue fills up
- with new organisms.
-
- A queue_lock parameter may be provided, which 'centers' the reallocation on
- a given process ID. This means that, after reallocating the queue, the
- process with that ID will keep still have the same ID on the new queue.
+ /*
+ * Reallocate reaper queue into a new circular queue with double the
+ * capacity. This function gets called whenever the reaper queue fills up
+ * with new organisms.
+ *
+ * A queue_lock parameter may be provided, which 'centers' the reallocation
+ * on a given process ID. This means that, after reallocating the queue, the
+ * process with that ID will keep still have the same ID on the new queue.
*/
uint32 new_capacity;
Process *new_queue;
@@ -174,7 +185,8 @@ static void realloc_queue(uint32 queue_lock)
fwrd_idx = queue_lock;
back_idx = (queue_lock - 1) % new_capacity;
- /* Copy all organisms that lie forward from queue lock.
+ /*
+ * Copy all organisms that lie forward from queue lock.
*/
while (TRUE) {
uint32 old_idx = fwrd_idx % g_capacity;
@@ -188,9 +200,10 @@ static void realloc_queue(uint32 queue_lock)
}
}
- /* Copy all organisms that lie backwards from queue lock, making sure to
- loop around the queue (with modulo '%') whenever the process index goes
- below zero.
+ /*
+ * Copy all organisms that lie backwards from queue lock, making sure to
+ * loop around the queue (with modulo '%') whenever the process index goes
+ * below zero.
*/
if (queue_lock != g_first) {
while (TRUE) {
@@ -207,7 +220,8 @@ static void realloc_queue(uint32 queue_lock)
}
}
- /* Free old reaper queue and re-link global pointer to new queue.
+ /*
+ * Free old reaper queue and re-link global pointer to new queue.
*/
free(g_procs);
g_capacity = new_capacity;
@@ -216,12 +230,14 @@ static void realloc_queue(uint32 queue_lock)
static uint32 get_new_proc_from_queue(uint32 queue_lock)
{
- /* Retrieve an unoccupied process ID from the reaper queue. This function
- gets called whenever a new organism is generated (born).
+ /*
+ * Retrieve an unoccupied process ID from the reaper queue. This function
+ * gets called whenever a new organism is generated (born).
*/
assert(g_is_init);
- /* If reaper queue is full, reallocate to double its current size.
+ /*
+ * If reaper queue is full, reallocate to double its current size.
*/
if (g_count == g_capacity) {
realloc_queue(queue_lock);
@@ -243,18 +259,20 @@ static uint32 get_new_proc_from_queue(uint32 queue_lock)
static void proc_create(uint32 address, uint32 size, uint32 queue_lock,
boolean allocate)
{
- /* Give birth to a new process! We must specify the address and size of the
- new organism.
+ /*
+ * Give birth to a new process! We must specify the address and size of the
+ * new organism.
*/
uint32 pidx;
assert(g_is_init);
assert(sal_mem_is_address_valid(address));
assert(sal_mem_is_address_valid(address + size - 1));
- /* When organisms are generated manually (by an user), we must explicitly
- allocate its entire memory block. When organisms replicate by themselves,
- we assume they have already allocated the child's memory, so we don't need
- to do it here.
+ /*
+ * When organisms are generated manually (by an user), we must explicitly
+ * allocate its entire memory block. When organisms replicate by themselves,
+ * we assume they have already allocated the child's memory, so we don't
+ * need to do it here.
*/
if (allocate) {
uint32 offset;
@@ -266,8 +284,9 @@ static void proc_create(uint32 address, uint32 size, uint32 queue_lock,
}
}
- /* Get a new process ID for the child process. Also, set initial state of
- the child process data structure.
+ /*
+ * Get a new process ID for the child process. Also, set initial state of
+ * the child process data structure.
*/
pidx = get_new_proc_from_queue(queue_lock);
g_procs[pidx].mb1a = address;
@@ -278,8 +297,9 @@ static void proc_create(uint32 address, uint32 size, uint32 queue_lock,
void sal_proc_create(uint32 address, uint32 mb1s)
{
- /* API function to create a new process. Memory address and size of new
- process must be provided.
+ /*
+ * API function to create a new process. Memory address and size of new
+ * process must be provided.
*/
assert(g_is_init);
assert(block_is_free_and_valid(address, mb1s));
@@ -288,7 +308,8 @@ void sal_proc_create(uint32 address, uint32 mb1s)
static void free_memory_block(uint32 address, uint32 size)
{
- /* Deallocate a memory block.
+ /*
+ * Deallocate a memory block.
*/
uint32 offset;
assert(sal_mem_is_address_valid(address));
@@ -306,7 +327,8 @@ static void free_memory_block(uint32 address, uint32 size)
static void free_memory_owned_by(uint32 pidx)
{
- /* Free memory specifically owned by the process with the given ID.
+ /*
+ * Free memory specifically owned by the process with the given ID.
*/
assert(g_is_init);
assert(pidx < g_capacity);
@@ -314,7 +336,8 @@ static void free_memory_owned_by(uint32 pidx)
free_memory_block(g_procs[pidx].mb1a, g_procs[pidx].mb1s);
if (g_procs[pidx].mb2s) {
- /* If process owns a child memory block, free it as well.
+ /*
+ * If process owns a child memory block, free it as well.
*/
free_memory_block(g_procs[pidx].mb2a, g_procs[pidx].mb2s);
}
@@ -322,7 +345,8 @@ static void free_memory_owned_by(uint32 pidx)
static void proc_kill(void)
{
- /* Kill process on bottom of reaper queue (the oldest process).
+ /*
+ * Kill process on bottom of reaper queue (the oldest process).
*/
assert(g_is_init);
assert(g_count);
@@ -330,7 +354,8 @@ static void proc_kill(void)
assert(g_last != UINT32_MAX);
assert(!sal_proc_is_free(g_first));
- /* Free up owned memory and reset process data structure back to zero.
+ /*
+ * Free up owned memory and reset process data structure back to zero.
*/
free_memory_owned_by(g_first);
memset(&g_procs[g_first], 0, sizeof(Process));
@@ -347,8 +372,9 @@ static void proc_kill(void)
void sal_proc_kill(void)
{
- /* API function to kill a process. Make sure that at least one process is
- alive, or 'assert()' will fail.
+ /*
+ * API function to kill a process. Make sure that at least one process is
+ * alive, or 'assert()' will fail.
*/
assert(g_is_init);
assert(g_count);
@@ -360,7 +386,8 @@ void sal_proc_kill(void)
static boolean block_is_allocated(uint32 address, uint32 size)
{
- /* Assert that a given memory block is fully allocated.
+ /*
+ * Assert that a given memory block is fully allocated.
*/
uint32 offset;
assert(g_is_init);
@@ -376,9 +403,11 @@ 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 allocated
- flags are set in place. IP and SP must be located in valid addresses.
+ /*
+ * 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
+ * allocated flags are set in place. IP and SP must be located in valid
+ * addresses.
*/
assert(g_is_init);
assert(pidx < g_capacity);
@@ -398,26 +427,29 @@ static boolean proc_is_valid(uint32 pidx)
static boolean module_is_valid(void)
{
- /* Check for validity of process module. This function only gets called
- when Salis is running in debug mode. It makes Salis **very** slow in
- comparison to when running optimized, but it is also **very** useful for
- debugging!
+ /*
+ * Check for validity of process module. This function only gets called when
+ * Salis is running in debug mode. It makes Salis **very** slow in
+ * comparison to when running optimized, but it is also **very** useful for
+ * debugging!
*/
uint32 pidx;
uint32 alloc_count = 0;
assert(g_is_init);
- /* Check that each individual process is in a valid state. We can do this
- in a multi-threaded way.
+ /*
+ * Check that each individual process is in a valid state. We can do this
+ * in a multi-threaded way.
*/
#pragma omp parallel for
for (pidx = 0; pidx < g_capacity; pidx++) {
assert(proc_is_valid(pidx));
}
- /* Iterate all processes, counting their memory blocks and adding up their
- memory block sizes. At the end, we compare the sums to the flag counters of
- the memory module.
+ /*
+ * Iterate all processes, counting their memory blocks and adding up their
+ * memory block sizes. At the end, we compare the sums to the flag counters of
+ * the memory module.
*/
for (pidx = 0; pidx < g_capacity; pidx++) {
if (!sal_proc_is_free(pidx)) {
@@ -436,7 +468,8 @@ static boolean module_is_valid(void)
static void on_fault(uint32 pidx)
{
- /* For now, faults do nothing.
+ /*
+ * For now, faults do nothing.
*/
assert(g_is_init);
assert(pidx < g_capacity);
@@ -446,8 +479,9 @@ static void on_fault(uint32 pidx)
static void increment_ip(uint32 pidx)
{
- /* After executing each instruction, increment the given organism's IP to
- the next valid address.
+ /*
+ * After executing each instruction, increment the given organism's IP to
+ * the next valid address.
*/
assert(g_is_init);
assert(pidx < g_capacity);
@@ -457,42 +491,49 @@ static void increment_ip(uint32 pidx)
g_procs[pidx].ip++;
}
- /* Wherever IP goes, SP follows. :P
+ /*
+ * Wherever IP goes, SP follows. :P
*/
g_procs[pidx].sp = g_procs[pidx].ip;
}
static boolean are_templates_complements(uint32 source, uint32 complement)
{
- /* Check whether 2 templates are complements. Templates are introduced in
- Salis-2.0 and they function in the same way as templates in the original
- Tierra. They consist of string of NOP0 and NOP1 instructions.
-
- We say that templates are complements whenever one is a 'negation' of
- another (i.e. they are reverse copies of each other). So, on the following
- example, the top template would be the complement of the bottom template.
-
- >>> NOP0 - NOP1 - NOP1
- >>> NOP1 - NOP0 - NOP0
-
- This function looks into 2 given addresses in memory and checks whether
- there are complementing templates on those addresses.
+ /*
+ * Check whether 2 templates are complements. Templates are introduced in
+ * Salis-2.0 and they function in the same way as templates in the original
+ * Tierra. They consist of string of NOP0 and NOP1 instructions.
+ *
+ * We say that templates are complements whenever one is a 'negation' of
+ * another (i.e. they are reverse copies of each other). So, on the
+ * following example, the top template would be the complement of the bottom
+ * template.
+ *
+ * >>> NOP0 - NOP1 - NOP1
+ * >>> NOP1 - NOP0 - NOP0
+ *
+ * This function looks into 2 given addresses in memory and checks whether
+ * there are complementing templates on those addresses.
*/
assert(g_is_init);
assert(sal_mem_is_address_valid(source));
assert(sal_mem_is_address_valid(complement));
assert(sal_is_template(sal_mem_get_inst(source)));
- while (sal_mem_is_address_valid(source) &&
- sal_is_template(sal_mem_get_inst(source))) {
- /* Iterate address by address, checking complementarity on each
- consecutive byte pair.
+ while (
+ sal_mem_is_address_valid(source) &&
+ sal_is_template(sal_mem_get_inst(source))
+ ) {
+ /*
+ * Iterate address by address, checking complementarity on each
+ * consecutive byte pair.
*/
uint8 inst_src;
uint8 inst_comp;
- /* If complement head moves to an invalid address, complementarity
- fails.
+ /*
+ * If complement head moves to an invalid address, complementarity
+ * fails.
*/
if (!sal_mem_is_address_valid(complement)) {
return FALSE;
@@ -514,18 +555,20 @@ static boolean are_templates_complements(uint32 source, uint32 complement)
complement++;
}
- /* If we get to the end of a template in the source head, and target has
- been complementary all the way through, we consider these blocks of memory
- 'complements'.
+ /*
+ * If we get to the end of a template in the source head, and target has
+ * been complementary all the way through, we consider these blocks of
+ * memory 'complements'.
*/
return TRUE;
}
static void increment_sp(uint32 pidx, boolean forward)
{
- /* Increment or decrement SP to the next valid address. This function gets
- called by organisms during jumps, searches, etc. (i.e. whenever the seeker
- pointer gets sent on a 'mission').
+ /*
+ * Increment or decrement SP to the next valid address. This function gets
+ * called by organisms during jumps, searches, etc. (i.e. whenever the
+ * seeker pointer gets sent on a 'mission').
*/
assert(g_is_init);
assert(pidx < g_capacity);
@@ -542,11 +585,12 @@ static void increment_sp(uint32 pidx, boolean forward)
static boolean jump_seek(uint32 pidx, boolean forward)
{
- /* Search (via the seeker pointer) for template to jump into. This gets
- called by organisms each cycle during a JMP instruction. Only when a valid
- template is found, will this function return TRUE. Otherwise it will return
- FALSE, signaling the calling process that a template has not yet been
- found.
+ /*
+ * Search (via the seeker pointer) for template to jump into. This gets
+ * called by organisms each cycle during a JMP instruction. Only when a
+ * valid template is found, will this function return TRUE. Otherwise it
+ * will return FALSE, signaling the calling process that a template has not
+ * yet been found.
*/
uint32 next_addr;
uint8 next_inst;
@@ -555,8 +599,9 @@ static boolean jump_seek(uint32 pidx, boolean forward)
assert(!sal_proc_is_free(pidx));
next_addr = g_procs[pidx].ip + 1;
- /* This function causes a 'fault' when there is no template right in front
- of the caller organism's instruction pointer.
+ /*
+ * This function causes a 'fault' when there is no template right in front
+ * of the caller organism's instruction pointer.
*/
if (!sal_mem_is_address_valid(next_addr)) {
on_fault(pidx);
@@ -572,8 +617,9 @@ static boolean jump_seek(uint32 pidx, boolean forward)
return FALSE;
}
- /* Check for complementarity. Increment seeker pointer if template has not
- been found yet.
+ /*
+ * Check for complementarity. Increment seeker pointer if template has not
+ * been found yet.
*/
if (are_templates_complements(next_addr, g_procs[pidx].sp)) {
return TRUE;
@@ -585,9 +631,10 @@ static boolean jump_seek(uint32 pidx, boolean forward)
static void jump(uint32 pidx)
{
- /* This gets called when an organism has finally found a template to jump
- into (see function above). Only when in debug mode, we make sure that the
- entire jump operation has been performed in a valid way.
+ /*
+ * This gets called when an organism has finally found a template to jump
+ * into (see function above). Only when in debug mode, we make sure that the
+ * entire jump operation has been performed in a valid way.
*/
#ifndef NDEBUG
uint32 next_addr;
@@ -610,11 +657,13 @@ static void jump(uint32 pidx)
static boolean addr_seek(uint32 pidx, boolean forward)
{
- /* Search (via the seeker pointer) for template address in memory. This
- gets called by organisms each cycle during a ADR instruction. Only when a
- valid template is found, will this function return TRUE. Otherwise it will
- return FALSE, signaling the calling process that a template has not yet
- been found. */
+ /*
+ * Search (via the seeker pointer) for template address in memory. This
+ * gets called by organisms each cycle during a ADR instruction. Only when a
+ * valid template is found, will this function return TRUE. Otherwise it
+ * will return FALSE, signaling the calling process that a template has not
+ * yet been found.
+ */
uint32 next1_addr;
uint32 next2_addr;
uint8 next1_inst;
@@ -625,12 +674,15 @@ static boolean addr_seek(uint32 pidx, boolean forward)
next1_addr = g_procs[pidx].ip + 1;
next2_addr = g_procs[pidx].ip + 2;
- /* This function causes a 'fault' when there is no register modifier right
- in front of the caller organism's instruction pointer, and a template just
- after that.
+ /*
+ * This function causes a 'fault' when there is no register modifier right
+ * in front of the caller organism's instruction pointer, and a template
+ * just after that.
*/
- if (!sal_mem_is_address_valid(next1_addr) ||
- !sal_mem_is_address_valid(next2_addr)) {
+ if (
+ !sal_mem_is_address_valid(next1_addr) ||
+ !sal_mem_is_address_valid(next2_addr)
+ ) {
on_fault(pidx);
increment_ip(pidx);
return FALSE;
@@ -645,8 +697,9 @@ static boolean addr_seek(uint32 pidx, boolean forward)
return FALSE;
}
- /* Check for complementarity. Increment seeker pointer if template has not
- been found yet.
+ /*
+ * Check for complementarity. Increment seeker pointer if template has not
+ * been found yet.
*/
if (are_templates_complements(next2_addr, g_procs[pidx].sp)) {
return TRUE;
@@ -656,12 +709,13 @@ static boolean addr_seek(uint32 pidx, boolean forward)
return FALSE;
}
-static boolean get_register_pointers(uint32 pidx, uint32_p *regs,
- uint32 reg_count)
-{
- /* This function is used to get pointers to a calling organism registers.
- Specifically, registers returned are those that will be used when executing
- the caller organism's current instruction.
+static boolean get_register_pointers(
+ uint32 pidx, uint32_p *regs, uint32 reg_count
+) {
+ /*
+ * This function is used to get pointers to a calling organism registers.
+ * Specifically, registers returned are those that will be used when
+ * executing the caller organism's current instruction.
*/
uint32 ridx;
assert(g_is_init);
@@ -671,15 +725,18 @@ static boolean get_register_pointers(uint32 pidx, uint32_p *regs,
assert(reg_count);
assert(reg_count < 4);
- /* Iterate 'reg_count' number of instructions forward from the IP, noting
- down all found register modifiers. If less than 'reg_count' modifiers are
- found, this function returns FALSE (triggering a 'fault').
+ /*
+ * Iterate 'reg_count' number of instructions forward from the IP, noting
+ * down all found register modifiers. If less than 'reg_count' modifiers are
+ * found, this function returns FALSE (triggering a 'fault').
*/
for (ridx = 0; ridx < reg_count; ridx++) {
uint32 mod_addr = g_procs[pidx].ip + 1 + ridx;
- if (!sal_mem_is_address_valid(mod_addr) ||
- !sal_is_mod(sal_mem_get_inst(mod_addr))) {
+ if (
+ !sal_mem_is_address_valid(mod_addr) ||
+ !sal_is_mod(sal_mem_get_inst(mod_addr))
+ ) {
return FALSE;
}
@@ -704,9 +761,10 @@ static boolean get_register_pointers(uint32 pidx, uint32_p *regs,
static void addr(uint32 pidx)
{
- /* This gets called when an organism has finally found a template and is
- ready to store its address. Only when in debug mode, we make sure that the
- entire search operation has been performed in a valid way.
+ /*
+ * This gets called when an organism has finally found a template and is
+ * ready to store its address. Only when in debug mode, we make sure that
+ * the entire search operation has been performed in a valid way.
*/
uint32_p reg;
@@ -726,7 +784,8 @@ static void addr(uint32 pidx)
assert(are_templates_complements(next2_addr, g_procs[pidx].sp));
#endif
- /* Store address of complement into the given register.
+ /*
+ * Store address of complement into the given register.
*/
if (!get_register_pointers(pidx, &reg, 1)) {
on_fault(pidx);
@@ -740,7 +799,8 @@ static void addr(uint32 pidx)
static void free_child_block_of(uint32 pidx)
{
- /* Free only the 'child' memory block (mb2) of the caller organism.
+ /*
+ * Free only the 'child' memory block (mb2) of the caller organism.
*/
assert(g_is_init);
assert(pidx < g_capacity);
@@ -753,11 +813,12 @@ static void free_child_block_of(uint32 pidx)
static void alloc(uint32 pidx, boolean forward)
{
- /* Allocate a 'child' memory block of size stored in the first given
- register, and save its address into the second given register. This
- function is the basis of Salisian reproduction. It's a fairly complicated
- function (as the seeker pointer must function in a procedural way), so it's
- divided into a series of steps, documented below.
+ /*
+ * Allocate a 'child' memory block of size stored in the first given
+ * register, and save its address into the second given register. This
+ * function is the basis of Salisian reproduction. It's a fairly complicated
+ * function (as the seeker pointer must function in a procedural way), so
+ * it's divided into a series of steps, documented below.
*/
uint32_p regs[2];
uint32 block_size;
@@ -765,9 +826,10 @@ static void alloc(uint32 pidx, boolean forward)
assert(pidx < g_capacity);
assert(!sal_proc_is_free(pidx));
- /* For this function to work, we need at least two register modifiers.
- Then, we check for all possible error conditions. If any error conditions
- are found, the instruction faults and returns.
+ /*
+ * For this function to work, we need at least two register modifiers.
+ * Then, we check for all possible error conditions. If any error conditions
+ * are found, the instruction faults and returns.
*/
if (!get_register_pointers(pidx, regs, 2)) {
on_fault(pidx);
@@ -777,7 +839,8 @@ static void alloc(uint32 pidx, boolean forward)
block_size = *regs[0];
- /* ERROR 1: requested child block is of size zero.
+ /*
+ * ERROR 1: requested child block is of size zero.
*/
if (!block_size) {
on_fault(pidx);
@@ -785,7 +848,8 @@ static void alloc(uint32 pidx, boolean forward)
return;
}
- /* ERROR 2: seeker pointer not adjacent to existing child block.
+ /*
+ * ERROR 2: seeker pointer not adjacent to existing child block.
*/
if (g_procs[pidx].mb2s) {
uint32 exp_addr;
@@ -803,7 +867,8 @@ static void alloc(uint32 pidx, boolean forward)
}
}
- /* No errors were detected. We thus handle all correct conditions.
+ /*
+ * No errors were detected. We thus handle all correct conditions.
* CONDITION 1: allocation was successful.
*/
if (g_procs[pidx].mb2s == block_size) {
@@ -812,8 +877,9 @@ static void alloc(uint32 pidx, boolean forward)
return;
}
- /* CONDITION 2: seeker pointer has collided with allocated space. We free
- child memory block and just continue searching.
+ /*
+ * CONDITION 2: seeker pointer has collided with allocated space. We free
+ * child memory block and just continue searching.
*/
if (sal_mem_is_allocated(g_procs[pidx].sp)) {
if (g_procs[pidx].mb2s) {
@@ -824,8 +890,9 @@ static void alloc(uint32 pidx, boolean forward)
return;
}
- /* CONDITION 3: no collision detected; enlarge child memory block and
- increment seeker pointer.
+ /*
+ * CONDITION 3: no collision detected; enlarge child memory block and
+ * increment seeker pointer.
*/
_sal_mem_set_allocated(g_procs[pidx].sp);
@@ -839,8 +906,9 @@ static void alloc(uint32 pidx, boolean forward)
static void swap(uint32 pidx)
{
- /* Swap parent and child memory blocks. This function is the basis of
- Salisian metabolism.
+ /*
+ * Swap parent and child memory blocks. This function is the basis of
+ * Salisian metabolism.
*/
assert(g_is_init);
assert(pidx < g_capacity);
@@ -862,7 +930,8 @@ static void swap(uint32 pidx)
static void split(uint32 pidx)
{
- /* Split child memory block into a new organism. A new baby is born. :-)
+ /*
+ * Split child memory block into a new organism. A new baby is born. :-)
*/
assert(g_is_init);
assert(pidx < g_capacity);
@@ -881,9 +950,10 @@ static void split(uint32 pidx)
static void one_reg_op(uint32 pidx, uint8 inst)
{
- /* Here we group all 1-register operations. These include incrementing,
- decrementing, placing zero or one on a register, and the negation
- operation.
+ /*
+ * Here we group all 1-register operations. These include incrementing,
+ * decrementing, placing zero or one on a register, and the negation
+ * operation.
*/
uint32_p reg;
assert(g_is_init);
@@ -928,9 +998,10 @@ static void one_reg_op(uint32 pidx, uint8 inst)
static void if_not_zero(uint32 pidx)
{
- /* Conditional operator. Like in most programming languages, this
- instruction is needed to allow organism execution to branch into different
- execution streams.
+ /*
+ * Conditional operator. Like in most programming languages, this
+ * instruction is needed to allow organism execution to branch into
+ * different execution streams.
*/
uint32_p reg;
assert(g_is_init);
@@ -953,8 +1024,9 @@ static void if_not_zero(uint32 pidx)
static void three_reg_op(uint32 pidx, uint8 inst)
{
- /* Here we group all 3-register arithmetic operations. These include
- addition, subtraction, multiplication and division.
+ /*
+ * Here we group all 3-register arithmetic operations. These include
+ * addition, subtraction, multiplication and division.
*/
uint32_p regs[3];
assert(g_is_init);
@@ -979,7 +1051,9 @@ static void three_reg_op(uint32 pidx, uint8 inst)
*regs[0] = *regs[1] * *regs[2];
break;
case DIVN:
- /* Division by 0 is not allowed and causes a fault. */
+ /*
+ * Division by 0 is not allowed and causes a fault.
+ */
if (!(*regs[2])) {
on_fault(pidx);
increment_ip(pidx);
@@ -997,16 +1071,19 @@ static void three_reg_op(uint32 pidx, uint8 inst)
static void load(uint32 pidx)
{
- /* Load an instruction from a given address into a specified register. This
- is used by organisms during their reproduction cycle.
+ /*
+ * Load an instruction from a given address into a specified register. This
+ * is used by organisms during their reproduction cycle.
*/
uint32_p regs[2];
assert(g_is_init);
assert(pidx < g_capacity);
assert(!sal_proc_is_free(pidx));
- if (!get_register_pointers(pidx, regs, 2) ||
- !sal_mem_is_address_valid(*regs[0])) {
+ if (
+ !get_register_pointers(pidx, regs, 2) ||
+ !sal_mem_is_address_valid(*regs[0])
+ ) {
on_fault(pidx);
increment_ip(pidx);
return;
@@ -1024,9 +1101,10 @@ static void load(uint32 pidx)
static boolean is_writeable_by(uint32 pidx, uint32 address)
{
- /* Check whether an organisms has writing rights on a specified address.
- Any organism may write to any valid address that is either self owned or
- not allocated.
+ /*
+ * Check whether an organisms has writing rights on a specified address.
+ * Any organism may write to any valid address that is either self owned or
+ * not allocated.
*/
assert(g_is_init);
assert(pidx < g_capacity);
@@ -1040,23 +1118,28 @@ static boolean is_writeable_by(uint32 pidx, uint32 address)
uint32 lo2 = g_procs[pidx].mb2a;
uint32 hi1 = lo1 + g_procs[pidx].mb1s;
uint32 hi2 = lo2 + g_procs[pidx].mb2s;
- return ((address >= lo1 && address < hi1) ||
- (address >= lo2 && address < hi2));
+ return (
+ (address >= lo1 && address < hi1) ||
+ (address >= lo2 && address < hi2)
+ );
}
}
static void write(uint32 pidx)
{
- /* Write instruction on a given register into a specified address. This is
- used by organisms during their reproduction cycle.
+ /*
+ * Write instruction on a given register into a specified address. This is
+ * used by organisms during their reproduction cycle.
*/
uint32_p regs[2];
assert(g_is_init);
assert(pidx < g_capacity);
assert(!sal_proc_is_free(pidx));
- if (!get_register_pointers(pidx, regs, 2) ||
- !sal_mem_is_address_valid(*regs[0]) || !sal_is_inst(*regs[1])) {
+ if (
+ !get_register_pointers(pidx, regs, 2) ||
+ !sal_mem_is_address_valid(*regs[0]) || !sal_is_inst(*regs[1])
+ ) {
on_fault(pidx);
increment_ip(pidx);
return;
@@ -1077,7 +1160,8 @@ static void write(uint32 pidx)
static void send(uint32 pidx)
{
- /* Send instruction on given register into the common sender.
+ /*
+ * Send instruction on given register into the common sender.
*/
uint32_p reg;
assert(g_is_init);
@@ -1102,9 +1186,10 @@ static void send(uint32 pidx)
static void receive(uint32 pidx)
{
- /* Receive a single instruction from the common receiver and store it into
- a specified register. In case the receiver is unset, it will return the
- NOP0 instruction.
+ /*
+ * Receive a single instruction from the common receiver and store it into
+ * a specified register. In case the receiver is unset, it will return the
+ * NOP0 instruction.
*/
uint32_p reg;
assert(g_is_init);
@@ -1124,8 +1209,9 @@ static void receive(uint32 pidx)
static void push(uint32 pidx)
{
- /* Push value on register into the stack. This is useful as a secondary
- memory resource.
+ /*
+ * Push value on register into the stack. This is useful as a secondary
+ * memory resource.
*/
uint32_p reg;
uint32 sidx;
@@ -1149,7 +1235,8 @@ static void push(uint32 pidx)
static void pop(uint32 pidx)
{
- /* Pop value from the stack into a given register.
+ /*
+ * Pop value from the stack into a given register.
*/
uint32_p reg;
uint32 sidx;
@@ -1175,8 +1262,9 @@ static void pop(uint32 pidx)
static void proc_cycle(uint32 pidx)
{
- /* Cycle a process once. Organisms will always execute one instruction per
- simulation cycle.
+ /*
+ * Cycle a process once. Organisms will always execute one instruction per
+ * simulation cycle.
*/
uint8 inst;
assert(g_is_init);
@@ -1252,16 +1340,18 @@ static void proc_cycle(uint32 pidx)
void _sal_proc_cycle(void)
{
- /* The process module cycle consists of a series of steps, which are needed
- to preserve overall correctness.
+ /*
+ * The process module cycle consists of a series of steps, which are needed
+ * to preserve overall correctness.
*/
assert(g_is_init);
assert(module_is_valid());
- /* Iterate through all organisms in the reaper queue. First organism to
- execute is the one pointed to by 'g_last' (the one on top of the queue).
- Last one to execute is 'g_first'. We go around the circular queue, making
- sure to modulo (%) around when iterator goes below zero.
+ /*
+ * Iterate through all organisms in the reaper queue. First organism to
+ * execute is the one pointed to by 'g_last' (the one on top of the queue).
+ * Last one to execute is 'g_first'. We go around the circular queue, making
+ * sure to modulo (%) around when iterator goes below zero.
*/
if (g_count) {
uint32 pidx = g_last;
@@ -1273,7 +1363,8 @@ void _sal_proc_cycle(void)
proc_cycle(pidx);
}
- /* Kill oldest processes whenever memory gets filled over capacity.
+ /*
+ * Kill oldest processes whenever memory gets filled over capacity.
*/
while (sal_mem_get_allocated() > sal_mem_get_capacity()) {
proc_kill();
diff --git a/src/render.c b/src/render.c
index a4ed262..66db0c4 100644
--- a/src/render.c
+++ b/src/render.c
@@ -9,28 +9,31 @@
#define BLOCK_FLAG 0x40
#define IP_FLAG 0x80
-static void apply_flag(uint32 origin, uint32 max_pos, uint32 cell_size,
- uint32 address, uint32 flag, uint8_p buffer)
-{
+static void apply_flag(
+ uint32 origin, uint32 max_pos, uint32 cell_size, uint32 address,
+ uint32 flag, uint8_p buffer
+) {
if (address >= origin && address < max_pos) {
- /* Flag falls inside rendered image. We can 'and' the bit to the
- corresponding pixel.
+ /*
+ * Flag falls inside rendered image. We can 'and' the bit to the
+ * corresponding pixel.
*/
uint32 pixel = (address - origin) / cell_size;
buffer[pixel] |= flag;
}
}
-void sal_ren_get_image(uint32 origin, uint32 cell_size, uint32 buff_size,
- uint8_p buffer)
-{
- /* Render a 1D image of a given section of memory, at a given resolution
- (zoom) and store it in a pre-allocated 'buffer'.
-
- On the Salis python handler we draw memory as a 1D 'image' on the WORLD
- page. If we were to render this image directly on python, it would be
- excruciatingly slow, as we have to iterate over large areas of memory!
- Therefore, this memory module comes with a built-in, super fast renderer.
+void sal_ren_get_image(
+ uint32 origin, uint32 cell_size, uint32 buff_size, uint8_p buffer
+) {
+ /*
+ * Render a 1D image of a given section of memory, at a given resolution
+ * (zoom) and store it in a pre-allocated 'buffer'.
+ *
+ * On the Salis python handler we draw memory as a 1D 'image' on the WORLD
+ * page. If we were to render this image directly on python, it would be
+ * excruciatingly slow, as we have to iterate over large areas of memory!
+ * Therefore, this memory module comes with a built-in, super fast renderer.
*/
uint32 i;
uint32 max_pos;
@@ -40,8 +43,9 @@ void sal_ren_get_image(uint32 origin, uint32 cell_size, uint32 buff_size,
assert(buff_size);
assert(buffer);
- /* We make use of openmp for multi-threaded looping. This allows even
- faster render times, wherever openmp is supported.
+ /*
+ * We make use of openmp for multi-threaded looping. This allows even faster
+ * render times, wherever openmp is supported.
*/
#pragma omp parallel for
for (i = 0; i < buff_size; i++) {
@@ -68,8 +72,9 @@ void sal_ren_get_image(uint32 origin, uint32 cell_size, uint32 buff_size,
buffer[i] |= (uint8)(alloc_flag);
}
- /* We also iterate through all processes and append extra bit flags to the
- rendered image signaling process IP position and memory block limits.
+ /*
+ * We also iterate through all processes and append extra bit flags to the
+ * rendered image signaling process IP position and memory block limits.
*/
max_pos = origin + (cell_size * buff_size);
@@ -78,12 +83,14 @@ void sal_ren_get_image(uint32 origin, uint32 cell_size, uint32 buff_size,
if (!sal_proc_is_free(i)) {
Process proc = sal_proc_get_proc(i);
apply_flag(origin, max_pos, cell_size, proc.ip, IP_FLAG, buffer);
- apply_flag(origin, max_pos, cell_size, proc.mb1a, BLOCK_FLAG,
- buffer);
+ apply_flag(
+ origin, max_pos, cell_size, proc.mb1a, BLOCK_FLAG, buffer
+ );
if (proc.mb2s) {
- apply_flag(origin, max_pos, cell_size, proc.mb2a, BLOCK_FLAG,
- buffer);
+ apply_flag(
+ origin, max_pos, cell_size, proc.mb2a, BLOCK_FLAG, buffer
+ );
}
}
}
diff --git a/src/salis.c b/src/salis.c
index 32a14b8..102ca49 100644
--- a/src/salis.c
+++ b/src/salis.c
@@ -9,8 +9,9 @@ static uint32 g_epoch;
void sal_main_init(uint32 order)
{
- /* Initialize all Salis modules to their initial states. We pass along any
- arguments to their respective modules.
+ /*
+ * Initialize all Salis modules to their initial states. We pass along any
+ * arguments to their respective modules.
*/
assert(!g_is_init);
_sal_mem_init(order);
@@ -21,10 +22,11 @@ void sal_main_init(uint32 order)
void sal_main_quit(void)
{
- /* Reset Salis and all of its modules back to zero. We may, thus, shutdown
- Salis and re-initialize it with different parameters without having to
- reload the library (useful, for example, when running data gathering
- scripts that must iterate through many save files).
+ /*
+ * Reset Salis and all of its modules back to zero. We may, thus, shutdown
+ * Salis and re-initialize it with different parameters without having to
+ * reload the library (useful, for example, when running data gathering
+ * scripts that must iterate through many save files).
*/
assert(g_is_init);
_sal_proc_quit();
@@ -37,8 +39,9 @@ void sal_main_quit(void)
void sal_main_load(string file_name)
{
- /* Load simulation state from file. This file must have been created by
- 'sal_main_save()'.
+ /*
+ * Load simulation state from file. This file must have been created by
+ * 'sal_main_save()'.
*/
FILE *file;
assert(!g_is_init);
@@ -56,9 +59,10 @@ void sal_main_load(string file_name)
void sal_main_save(string file_name)
{
- /* Save simulation state to a file. This file may later be re-loaded with
- 'sal_main_load()'. We save in binary format (to save space), which means
- save files might not be entirely portable.
+ /*
+ * Save simulation state to a file. This file may later be re-loaded with
+ * 'sal_main_load()'. We save in binary format (to save space), which means
+ * save files might not be entirely portable.
*/
FILE *file;
assert(g_is_init);
@@ -76,21 +80,24 @@ void sal_main_save(string file_name)
boolean sal_main_is_init(void)
{
- /* Check if Salis is currently initialized/running.
+ /*
+ * Check if Salis is currently initialized/running.
*/
return g_is_init;
}
-/* Getter methods for the Salis main module.
+/*
+* Getter methods for the Salis main module.
*/
UINT32_GETTER(main, cycle)
UINT32_GETTER(main, epoch)
void sal_main_cycle(void)
{
- /* Cycle the Salis simulator once. The combination of a cycle * epoch
- counter allows us to track simulations for an insane period of time
- (2^64 cycles).
+ /*
+ * Cycle the Salis simulator once. The combination of a cycle * epoch
+ * counter allows us to track simulations for an insane period of time
+ * (2^64 cycles).
*/
g_cycle++;
@@ -98,7 +105,8 @@ void sal_main_cycle(void)
g_epoch++;
}
- /* Cycle all of the Salis modules.
+ /*
+ * Cycle all of the Salis modules.
*/
_sal_mem_cycle();
_sal_evo_cycle();