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
commit6b1444aa3918382aba127c16c671f045a3586e53 (patch)
tree08b6b1e55383d63ba4e5824071620a35f737925c /src
parent2250b4db92bd272dbb1fd717eb791e293c17e37a (diff)
Common pipe replaced with sender/receiver functors.
[#27] C library now only takes care of relaying data to/from functors, which must be provided by the wrapping application (in this case, a new python module named 'common.py').
Diffstat (limited to 'src')
-rw-r--r--src/common.c66
-rw-r--r--src/process.c6
-rw-r--r--src/salis.c9
3 files changed, 29 insertions, 52 deletions
diff --git a/src/common.c b/src/common.c
index 3653252..402320e 100644
--- a/src/common.c
+++ b/src/common.c
@@ -1,69 +1,49 @@
#include <assert.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <unistd.h>
#include "types.h"
#include "instset.h"
#include "common.h"
-static boolean g_is_init;
-static int g_file_desc;
+static Sender g_sender;
+static Receiver g_receiver;
-void _sal_comm_init(string pipe)
+void sal_comm_set_sender(Sender sender)
{
- /* Initialize the common pipe. This module is the only one on Salis that
- makes use of Linux specific headers and types. If you want, feel free to
- port this code into other platforms (should be easy). If you do so, let me
- know and we can incorporate it into the Salis repository.
+ /* Set sender functor. Whenever an organism calls the SEND instruction,
+ this function will get called. When unset, SEND instruction is ignored.
*/
- assert(!g_is_init);
- mkfifo(pipe, 0666);
- g_is_init = TRUE;
-
- /* It's important to open the FIFO file in non-blocking mode, or else the
- simulators might halt if the pipe becomes empty.
- */
- g_file_desc = open(pipe, O_RDWR | O_NONBLOCK);
- assert(g_file_desc != -1);
+ assert(sender);
+ g_sender = sender;
}
-void _sal_comm_quit(void)
+void sal_comm_set_receiver(Receiver receiver)
{
- /* Close the common pipe FIFO file from within this instance. An empty pipe
- file will remain unless it gets manually deleted.
+ /* Set receiver functor. Whenever an organism calls the RCVE instruction,
+ this function will get called. When unset, RCVE instruction is ignored.
*/
- assert(g_is_init);
- close(g_file_desc);
- g_is_init = FALSE;
- g_file_desc = 0;
+ assert(receiver);
+ g_receiver = receiver;
}
void _sal_comm_send(uint8 inst)
{
- /* Send a single byte (instruction) to the common pipe. This function is
- called by processes that execute the SEND instruction. Hopefully, some of
- them 'learn' to use this as an advantage.
-
- In the future, I want to make the common pipe able to communicate across
- local networks (LANs) and over the Internet.
+ /* Send a single byte (instruction) to the sender. This function is called
+ by processes that execute the SEND instruction.
*/
- assert(g_is_init);
assert(sal_is_inst(inst));
- write(g_file_desc, &inst, 1);
+
+ if (g_sender) {
+ g_sender(inst);
+ }
}
uint8 _sal_comm_receive(void)
{
- /* Receive a single byte (instruction) from the common pipe. This function
- is called by processes that execute the RCVE instruction. If the pipe is
- empty, this function returns the NOP0 instruction.
+ /* 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.
*/
- uint8 inst;
- ssize_t res;
- assert(g_is_init);
- res = read(g_file_desc, &inst, 1);
-
- if (res) {
+ if (g_receiver) {
+ uint8 inst = g_receiver();
assert(sal_is_inst(inst));
return inst;
} else {
diff --git a/src/process.c b/src/process.c
index 2b9fff8..eb89a8d 100644
--- a/src/process.c
+++ b/src/process.c
@@ -1077,7 +1077,7 @@ static void write(uint32 pidx)
static void send(uint32 pidx)
{
- /* Send instruction on given register into the common pipe.
+ /* Send instruction on given register into the common sender.
*/
uint32_p reg;
assert(g_is_init);
@@ -1102,8 +1102,8 @@ static void send(uint32 pidx)
static void receive(uint32 pidx)
{
- /* Receive a single instruction from the common pipe and store it into a
- specified register. In case the common pipe is empty, it will return the
+ /* 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;
diff --git a/src/salis.c b/src/salis.c
index 1aae1fa..32a14b8 100644
--- a/src/salis.c
+++ b/src/salis.c
@@ -7,14 +7,13 @@ static boolean g_is_init;
static uint32 g_cycle;
static uint32 g_epoch;
-void sal_main_init(uint32 order, string pipe)
+void sal_main_init(uint32 order)
{
/* 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);
- _sal_comm_init(pipe);
_sal_evo_init();
_sal_proc_init();
g_is_init = TRUE;
@@ -30,17 +29,16 @@ void sal_main_quit(void)
assert(g_is_init);
_sal_proc_quit();
_sal_evo_quit();
- _sal_comm_quit();
_sal_mem_quit();
g_is_init = FALSE;
g_cycle = 0;
g_epoch = 0;
}
-void sal_main_load(string file_name, string pipe)
+void sal_main_load(string file_name)
{
/* Load simulation state from file. This file must have been created by
- 'sal_main_save()'. File name of common pipe must also be provided.
+ 'sal_main_save()'.
*/
FILE *file;
assert(!g_is_init);
@@ -54,7 +52,6 @@ void sal_main_load(string file_name, string pipe)
_sal_evo_load_from(file);
_sal_proc_load_from(file);
fclose(file);
- _sal_comm_init(pipe);
}
void sal_main_save(string file_name)