Changeset - 1ae65b0b574e
.gitignore
Show inline comments
 
target
 
/.idea
 
**/*.rs.bk
 
Cargo.lock
 
main
 
examples/*/*.exe
 
examples/*.dll
 
examples/*.dll
 
examples/reowolf*
 
logs
 
\ No newline at end of file
examples/1_minimal/amy.c
Show inline comments
 
new file 100644
 
#include <stdio.h>
 
#include <string.h>
 
#include "../../reowolf.h"
 
#include "../utility.c"
 

	
 
int main(int argc, char** argv) {
 
	char * pdl_ptr = buffer_pdl("eg_protocols.pdl");
 
	size_t pdl_len = strlen(pdl_ptr);
 
	Arc_ProtocolDescription * pd = protocol_description_parse(pdl_ptr, pdl_len);
 
	size_t err_len;
 
	printf("Ptr is %p.\nErr is `%s`.\n", pd, reowolf_error_peek(&err_len));
 
	free(pdl_ptr);
 
	return 0;
 
}
 
\ No newline at end of file
examples/1_minimal/make.sh
Show inline comments
 
new file 100644
 
#!/bin/sh
 

	
 
LIB_PATH="../../target/release"
 
gcc -L $LIB_PATH -lreowolf_rs -Wl,-R$LIB_PATH amy.c -o ./amy
examples/1_minimal/reowolf.h
Show inline comments
 
new file 100644
 
/* CBindgen generated */
 

	
 
#ifndef REOWOLF_HEADER_DEFINED
 
#define REOWOLF_HEADER_DEFINED
 

	
 
#include <stdarg.h>
 
#include <stdbool.h>
 
#include <stdint.h>
 
#include <stdlib.h>
 

	
 
typedef enum {
 
  Active,
 
  Passive,
 
} EndpointPolarity;
 

	
 
typedef enum {
 
  Putter,
 
  Getter,
 
} Polarity;
 

	
 
typedef struct Arc_ProtocolDescription Arc_ProtocolDescription;
 

	
 
typedef struct Connector Connector;
 

	
 
typedef struct Payload Payload;
 

	
 
typedef int32_t ErrorCode;
 

	
 
typedef uint32_t ConnectorId;
 

	
 
typedef uint32_t PortSuffix;
 

	
 
typedef struct {
 
  ConnectorId connector_id;
 
  PortSuffix u32_suffix;
 
} PortId;
 

	
 
/**
 
 * Given
 
 * - an initialized connector in setup or connecting state,
 
 * - a string slice for the component's identifier in the connector's configured protocol description,
 
 * - a set of ports (represented as a slice; duplicates are ignored) in the native component's interface,
 
 * the connector creates a new (internal) protocol component C, such that the set of native ports are moved to C.
 
 * Usable in {setup, communication} states.
 
 */
 
ErrorCode connector_add_component(Connector *connector,
 
                                  const uint8_t *ident_ptr,
 
                                  uintptr_t ident_len,
 
                                  const PortId *ports_ptr,
 
                                  uintptr_t ports_len);
 

	
 
/**
 
 * Given
 
 * - an initialized connector in setup or connecting state,
 
 * - a utf-8 encoded socket address,
 
 * - the logical polarity of P,
 
 * - the "physical" polarity in {Active, Passive} of the endpoint through which P's peer will be discovered,
 
 * returns P, a port newly added to the native interface.
 
 */
 
ErrorCode connector_add_net_port(Connector *connector,
 
                                 const uint8_t *addr_str_ptr,
 
                                 uintptr_t addr_str_len,
 
                                 Polarity port_polarity,
 
                                 EndpointPolarity endpoint_polarity,
 
                                 PortId *port);
 

	
 
/**
 
 * Given an initialized connector in setup or connecting state,
 
 * - Creates a new directed port pair with logical channel putter->getter,
 
 * - adds the ports to the native component's interface,
 
 * - and returns them using the given out pointers.
 
 * Usable in {setup, communication} states.
 
 */
 
void connector_add_port_pair(Connector *connector, PortId *out_putter, PortId *out_getter);
 

	
 
/**
 
 * Connects this connector to the distributed system of connectors reachable through endpoints,
 
 * Usable in setup state, and changes the state to communication.
 
 */
 
ErrorCode connector_connect(Connector *connector, int64_t timeout_millis);
 

	
 
/**
 
 * Destroys the given a pointer to the connector on the heap, freeing its resources.
 
 * Usable in {setup, communication} states.
 
 */
 
void connector_destroy(Connector *connector);
 

	
 
ErrorCode connector_get(Connector *connector, PortId port);
 

	
 
const uint8_t *connector_gotten_bytes(Connector *connector, PortId port, uintptr_t *len);
 

	
 
/**
 
 * Allocates a new connector on the heap and returning a pointer,
 
 * given an initialized protocol description.
 
 */
 
Connector *connector_new(const Arc_ProtocolDescription *pd);
 

	
 
/**
 
 * Initializes `out` with a new connector using the given protocol description as its configuration.
 
 * The connector uses the given (internal) connector ID.
 
 */
 
Connector *connector_new_with_id(const Arc_ProtocolDescription *pd, ConnectorId cid);
 

	
 
intptr_t connector_next_batch(Connector *connector);
 

	
 
/**
 
 * Convenience function combining the functionalities of
 
 * "payload_new" with "connector_put_payload".
 
 */
 
ErrorCode connector_put_bytes(Connector *connector,
 
                              PortId port,
 
                              const uint8_t *bytes_ptr,
 
                              uintptr_t bytes_len);
 

	
 
ErrorCode connector_put_payload(Connector *connector, PortId port, Payload *payload);
 

	
 
ErrorCode connector_put_payload_cloning(Connector *connector, PortId port, const Payload *payload);
 

	
 
intptr_t connector_sync(Connector *connector, int64_t timeout_millis);
 

	
 
/**
 
 * Given an initialized protocol description, initializes `out` with a clone which can be independently created or destroyed.
 
 */
 
Arc_ProtocolDescription *protocol_description_clone(const Arc_ProtocolDescription *pd);
 

	
 
/**
 
 * Destroys the given initialized protocol description and frees its resources.
 
 */
 
void protocol_description_destroy(Arc_ProtocolDescription *pd);
 

	
 
/**
 
 * Parses the utf8-encoded string slice to initialize a new protocol description object.
 
 * - On success, initializes `out` and returns 0
 
 * - On failure, stores an error string (see `reowolf_error_peek`) and returns -1
 
 */
 
Arc_ProtocolDescription *protocol_description_parse(const uint8_t *pdl, uintptr_t pdl_len);
 

	
 
/**
 
 * Returns length (via out pointer) and pointer (via return value) of the last Reowolf error.
 
 * - pointer is NULL iff there was no last error
 
 * - data at pointer is null-delimited
 
 * - len does NOT include the length of the null-delimiter
 
 */
 
const uint8_t *reowolf_error_peek(uintptr_t *len);
 

	
 
#endif /* REOWOLF_HEADER_DEFINED */
examples/cpy_dll.sh
Show inline comments
 
new file 100644
 
cp ./../target/release/reowolf_rs.dll ./ --force
examples/eg_protocols.pdl
Show inline comments
 

	
 
primitive forward(in i, out o) {
 
	while(true) synchronous {
 
		put(o, get(i));
 
	}
 
}
 
composite dynamic(in i, out o) {
 
	new forward(i, o);
 
}
 
primitive sync(in i, out o) {
 
	while(true) synchronous {
 
		if(fires(i)) {
 
			put(o, get(i));
 
		}
 
	}
 
}
 

	
 
primitive sync_two(in ia, in ib, out oa, out ob) {
 
	while(true) synchronous {
 
		if (fires(ia)) {
 
			put(oa, get(ia));
 
			put(ob, get(ib));
 
		}
 
	}
 
}
 

	
 
primitive xor_three(in ai, out ao, in bi, out bo, in ci, out co) {
 
	synchronous {
 
		if      (fires(ai)) put(ao, get(ai));
 
		else if (fires(bi)) put(bo, get(bi));
 
		else                put(co, get(ci)); 
 
	}
 
}
 
\ No newline at end of file
 
primitive foo(){}
 
\ No newline at end of file
examples/old/1_socketlike/amy.c
Show inline comments
 
file renamed from examples/1_socketlike/amy.c to examples/old/1_socketlike/amy.c
examples/old/1_socketlike/bob.c
Show inline comments
 
file renamed from examples/1_socketlike/bob.c to examples/old/1_socketlike/bob.c
examples/old/1_socketlike/make.sh
Show inline comments
 
file renamed from examples/1_socketlike/make.sh to examples/old/1_socketlike/make.sh
examples/old/2_dynamic_pdl/amy.c
Show inline comments
 
file renamed from examples/2_dynamic_pdl/amy.c to examples/old/2_dynamic_pdl/amy.c
examples/old/2_dynamic_pdl/make.sh
Show inline comments
 
file renamed from examples/2_dynamic_pdl/make.sh to examples/old/2_dynamic_pdl/make.sh
examples/old/3_atomicity/amy.c
Show inline comments
 
file renamed from examples/3_atomicity/amy.c to examples/old/3_atomicity/amy.c
examples/old/3_atomicity/bob.c
Show inline comments
 
file renamed from examples/3_atomicity/bob.c to examples/old/3_atomicity/bob.c
examples/old/3_atomicity/make.sh
Show inline comments
 
file renamed from examples/3_atomicity/make.sh to examples/old/3_atomicity/make.sh
examples/old/4_nondeterminism/amy.c
Show inline comments
 
file renamed from examples/4_nondeterminism/amy.c to examples/old/4_nondeterminism/amy.c
examples/old/4_nondeterminism/make.sh
Show inline comments
 
file renamed from examples/4_nondeterminism/make.sh to examples/old/4_nondeterminism/make.sh
examples/old/5_recovery/amy.c
Show inline comments
 
file renamed from examples/5_recovery/amy.c to examples/old/5_recovery/amy.c
examples/old/5_recovery/bob.c
Show inline comments
 
file renamed from examples/5_recovery/bob.c to examples/old/5_recovery/bob.c
examples/old/5_recovery/make.sh
Show inline comments
 
file renamed from examples/5_recovery/make.sh to examples/old/5_recovery/make.sh
examples/old/6_constraint_solve/main.c
Show inline comments
 
file renamed from examples/6_constraint_solve/main.c to examples/old/6_constraint_solve/main.c
examples/old/6_constraint_solve/make.sh
Show inline comments
 
file renamed from examples/6_constraint_solve/make.sh to examples/old/6_constraint_solve/make.sh
examples/old/REMINDER dll is a symlink.txt
Show inline comments
 
file renamed from examples/REMINDER dll is a symlink.txt to examples/old/REMINDER dll is a symlink.txt
examples/old/eg_protocols.pdl
Show inline comments
 
new file 100644
 

	
 
primitive forward(in i, out o) {
 
	while(true) synchronous {
 
		put(o, get(i));
 
	}
 
}
 
composite dynamic(in i, out o) {
 
	new forward(i, o);
 
}
 
primitive sync(in i, out o) {
 
	while(true) synchronous {
 
		if(fires(i)) {
 
			put(o, get(i));
 
		}
 
	}
 
}
 

	
 
primitive sync_two(in ia, in ib, out oa, out ob) {
 
	while(true) synchronous {
 
		if (fires(ia)) {
 
			put(oa, get(ia));
 
			put(ob, get(ib));
 
		}
 
	}
 
}
 

	
 
primitive xor_three(in ai, out ao, in bi, out bo, in ci, out co) {
 
	synchronous {
 
		if      (fires(ai)) put(ao, get(ai));
 
		else if (fires(bi)) put(bo, get(bi));
 
		else                put(co, get(ci)); 
 
	}
 
}
 
\ No newline at end of file
examples/old/utility.c
Show inline comments
 
new file 100644
 
#include <stdio.h>
 
#include <stdlib.h>
 
#include <errno.h>
 

	
 
void check(const char* phase, int code) {
 
	if (code < 0) {
 
		printf("ERR %d in phase `%s`. Err was `%s`\nEXITING!\n",
 
			code, phase, connector_error_peek());
 
		exit(1);
 
	}
 
}
 

	
 
// allocates a buffer!
 
char * buffer_pdl(char * filename) {
 
	FILE *f = fopen(filename, "rb");
 
	if (f == NULL) {
 
		printf("Opening pdl file returned errno %d!\n", errno);
 
		exit(1);
 
	}
 
	fseek(f, 0, SEEK_END);
 
	long fsize = ftell(f);
 
	fseek(f, 0, SEEK_SET);
 
	char *pdl = malloc(fsize + 1);
 
	fread(pdl, 1, fsize, f);
 
	fclose(f);
 
	pdl[fsize] = 0;
 
	return pdl;
 
}
 
\ No newline at end of file
examples/reowolf_rs.dll
Show inline comments
 
binary diff not shown
examples/utility.c
Show inline comments
 
#include <stdio.h>
 
#include <stdlib.h>
 
#include <errno.h>
 

	
 
void check(const char* phase, int code) {
 
	if (code < 0) {
 
		printf("ERR %d in phase `%s`. Err was `%s`\nEXITING!\n",
 
			code, phase, connector_error_peek());
 
		exit(1);
 
	}
 
}
 

	
 
// allocates a buffer!
 
char * buffer_pdl(char * filename) {
 
	FILE *f = fopen(filename, "rb");
 
	if (f == NULL) {
 
		printf("Opening pdl file returned errno %d!\n", errno);
 
		exit(1);
 
	}
 
	fseek(f, 0, SEEK_END);
 
	long fsize = ftell(f);
 
	fseek(f, 0, SEEK_SET);
 
	char *pdl = malloc(fsize + 1);
 
	fread(pdl, 1, fsize, f);
reowolf.h
Show inline comments
 
new file 100644
 
/* CBindgen generated */
 

	
 
#ifndef REOWOLF_HEADER_DEFINED
 
#define REOWOLF_HEADER_DEFINED
 

	
 
#include <stdarg.h>
 
#include <stdbool.h>
 
#include <stdint.h>
 
#include <stdlib.h>
 

	
 
typedef enum {
 
  Active,
 
  Passive,
 
} EndpointPolarity;
 

	
 
typedef enum {
 
  Putter,
 
  Getter,
 
} Polarity;
 

	
 
typedef struct Arc_ProtocolDescription Arc_ProtocolDescription;
 

	
 
typedef struct Connector Connector;
 

	
 
typedef struct Payload Payload;
 

	
 
typedef int32_t ErrorCode;
 

	
 
typedef uint32_t ConnectorId;
 

	
 
typedef uint32_t PortSuffix;
 

	
 
typedef struct {
 
  ConnectorId connector_id;
 
  PortSuffix u32_suffix;
 
} PortId;
 

	
 
/**
 
 * Given
 
 * - an initialized connector in setup or connecting state,
 
 * - a string slice for the component's identifier in the connector's configured protocol description,
 
 * - a set of ports (represented as a slice; duplicates are ignored) in the native component's interface,
 
 * the connector creates a new (internal) protocol component C, such that the set of native ports are moved to C.
 
 * Usable in {setup, communication} states.
 
 */
 
ErrorCode connector_add_component(Connector *connector,
 
                                  const uint8_t *ident_ptr,
 
                                  uintptr_t ident_len,
 
                                  const PortId *ports_ptr,
 
                                  uintptr_t ports_len);
 

	
 
/**
 
 * Given
 
 * - an initialized connector in setup or connecting state,
 
 * - a utf-8 encoded socket address,
 
 * - the logical polarity of P,
 
 * - the "physical" polarity in {Active, Passive} of the endpoint through which P's peer will be discovered,
 
 * returns P, a port newly added to the native interface.
 
 */
 
ErrorCode connector_add_net_port(Connector *connector,
 
                                 const uint8_t *addr_str_ptr,
 
                                 uintptr_t addr_str_len,
 
                                 Polarity port_polarity,
 
                                 EndpointPolarity endpoint_polarity,
 
                                 PortId *port);
 

	
 
/**
 
 * Given an initialized connector in setup or connecting state,
 
 * - Creates a new directed port pair with logical channel putter->getter,
 
 * - adds the ports to the native component's interface,
 
 * - and returns them using the given out pointers.
 
 * Usable in {setup, communication} states.
 
 */
 
void connector_add_port_pair(Connector *connector, PortId *out_putter, PortId *out_getter);
 

	
 
/**
 
 * Connects this connector to the distributed system of connectors reachable through endpoints,
 
 * Usable in setup state, and changes the state to communication.
 
 */
 
ErrorCode connector_connect(Connector *connector, int64_t timeout_millis);
 

	
 
/**
 
 * Destroys the given a pointer to the connector on the heap, freeing its resources.
 
 * Usable in {setup, communication} states.
 
 */
 
void connector_destroy(Connector *connector);
 

	
 
ErrorCode connector_get(Connector *connector, PortId port);
 

	
 
const uint8_t *connector_gotten_bytes(Connector *connector, PortId port, uintptr_t *len);
 

	
 
/**
 
 * Allocates a new connector on the heap and returning a pointer,
 
 * given an initialized protocol description.
 
 */
 
Connector *connector_new(const Arc_ProtocolDescription *pd);
 

	
 
/**
 
 * Initializes `out` with a new connector using the given protocol description as its configuration.
 
 * The connector uses the given (internal) connector ID.
 
 */
 
Connector *connector_new_with_id(const Arc_ProtocolDescription *pd, ConnectorId cid);
 

	
 
intptr_t connector_next_batch(Connector *connector);
 

	
 
/**
 
 * Convenience function combining the functionalities of
 
 * "payload_new" with "connector_put_payload".
 
 */
 
ErrorCode connector_put_bytes(Connector *connector,
 
                              PortId port,
 
                              const uint8_t *bytes_ptr,
 
                              uintptr_t bytes_len);
 

	
 
ErrorCode connector_put_payload(Connector *connector, PortId port, Payload *payload);
 

	
 
ErrorCode connector_put_payload_cloning(Connector *connector, PortId port, const Payload *payload);
 

	
 
intptr_t connector_sync(Connector *connector, int64_t timeout_millis);
 

	
 
/**
 
 * Given an initialized protocol description, initializes `out` with a clone which can be independently created or destroyed.
 
 */
 
Arc_ProtocolDescription *protocol_description_clone(const Arc_ProtocolDescription *pd);
 

	
 
/**
 
 * Destroys the given initialized protocol description and frees its resources.
 
 */
 
void protocol_description_destroy(Arc_ProtocolDescription *pd);
 

	
 
/**
 
 * Parses the utf8-encoded string slice to initialize a new protocol description object.
 
 * - On success, initializes `out` and returns 0
 
 * - On failure, stores an error string (see `reowolf_error_peek`) and returns -1
 
 */
 
Arc_ProtocolDescription *protocol_description_parse(const uint8_t *pdl, uintptr_t pdl_len);
 

	
 
/**
 
 * Returns length (via out pointer) and pointer (via return value) of the last Reowolf error.
 
 * - pointer is NULL iff there was no last error
 
 * - data at pointer is null-delimited
 
 * - len does NOT include the length of the null-delimiter
 
 */
 
const uint8_t *reowolf_error_peek(uintptr_t *len);
 

	
 
#endif /* REOWOLF_HEADER_DEFINED */
src/common.rs
Show inline comments
 
@@ -52,25 +52,25 @@ pub struct U32Stream {
 
#[repr(transparent)]
 
pub struct PortId(Id);
 
#[derive(
 
    Copy, Clone, Eq, PartialEq, Ord, Hash, PartialOrd, serde::Serialize, serde::Deserialize,
 
)]
 
pub struct FiringVar(pub(crate) PortId);
 
#[derive(
 
    Copy, Clone, Eq, PartialEq, Ord, Hash, PartialOrd, serde::Serialize, serde::Deserialize,
 
)]
 
pub struct ProtoComponentId(Id);
 

	
 
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
 
#[repr(C)]
 
// #[repr(C)]
 
pub struct Payload(Arc<Vec<u8>>);
 

	
 
#[derive(
 
    Debug, Eq, PartialEq, Clone, Hash, Copy, Ord, PartialOrd, serde::Serialize, serde::Deserialize,
 
)]
 
#[repr(C)]
 
pub enum Polarity {
 
    Putter, // output port (from the perspective of the component)
 
    Getter, // input port (from the perspective of the component)
 
}
 
#[derive(
 
    Debug, Eq, PartialEq, Clone, Hash, Copy, Ord, PartialOrd, serde::Serialize, serde::Deserialize,
src/runtime/communication.rs
Show inline comments
 
@@ -81,25 +81,25 @@ impl Connector {
 
        let Self { unphased, phased } = self;
 
        if !unphased.native_ports.contains(&port) {
 
            return Err(PortUnavailable);
 
        }
 
        match unphased.port_info.polarities.get(&port) {
 
            Some(p) if *p == expect_polarity => {}
 
            Some(_) => return Err(WrongPolarity),
 
            None => return Err(UnknownPolarity),
 
        }
 
        match phased {
 
            ConnectorPhased::Setup { .. } => Err(NotConnected),
 
            ConnectorPhased::Communication(comm) => {
 
                let batch = comm.native_batches.last_mut().unwrap(); // length >= invariant
 
                let batch = comm.native_batches.last_mut().unwrap(); // length >= 1 is invariant
 
                Ok(batch)
 
            }
 
        }
 
    }
 
    pub fn put(&mut self, port: PortId, payload: Payload) -> Result<(), PortOpError> {
 
        use PortOpError::*;
 
        let batch = self.port_op_access(port, Putter)?;
 
        if batch.to_put.contains_key(&port) {
 
            Err(MultipleOpsOnPort)
 
        } else {
 
            batch.to_put.insert(port, payload);
 
            Ok(())
src/runtime/ffi.rs
Show inline comments
 
@@ -19,35 +19,35 @@ impl StoredError {
 
    }
 
    fn debug_store<E: Debug>(&mut self, error: &E) {
 
        let _ = write!(&mut self.buf, "{:?}", error);
 
        self.buf.push(Self::NULL_TERMINATOR);
 
    }
 
    fn tl_debug_store<E: Debug>(error: &E) {
 
        STORED_ERROR.with(|stored_error| {
 
            let mut stored_error = stored_error.borrow_mut();
 
            stored_error.clear();
 
            stored_error.debug_store(error);
 
        })
 
    }
 
    // fn bytes_store(&mut self, bytes: &[u8]) {
 
    //     let _ = self.buf.write_all(bytes);
 
    //     self.buf.push(Self::NULL_TERMINATOR);
 
    // }
 
    // fn tl_bytes_store(bytes: &[u8]) {
 
    //     STORED_ERROR.with(|stored_error| {
 
    //         let mut stored_error = stored_error.borrow_mut();
 
    //         stored_error.clear();
 
    //         stored_error.bytes_store(bytes);
 
    //     })
 
    // }
 
    fn bytes_store(&mut self, bytes: &[u8]) {
 
        let _ = self.buf.write_all(bytes);
 
        self.buf.push(Self::NULL_TERMINATOR);
 
    }
 
    fn tl_bytes_store(bytes: &[u8]) {
 
        STORED_ERROR.with(|stored_error| {
 
            let mut stored_error = stored_error.borrow_mut();
 
            stored_error.clear();
 
            stored_error.bytes_store(bytes);
 
        })
 
    }
 
    fn tl_clear() {
 
        STORED_ERROR.with(|stored_error| {
 
            let mut stored_error = stored_error.borrow_mut();
 
            stored_error.clear();
 
        })
 
    }
 
    fn tl_bytes_peek() -> (*const u8, usize) {
 
        STORED_ERROR.with(|stored_error| {
 
            let stored_error = stored_error.borrow();
 
            match stored_error.buf.len() {
 
                0 => (core::ptr::null(), 0), // no error!
 
                n => {
 
@@ -77,79 +77,74 @@ pub unsafe extern "C" fn reowolf_error_peek(len: *mut usize) -> *const u8 {
 
    err_ptr
 
}
 

	
 
///////////////////// PROTOCOL DESCRIPTION //////////////////////////
 

	
 
/// Parses the utf8-encoded string slice to initialize a new protocol description object.
 
/// - On success, initializes `out` and returns 0
 
/// - On failure, stores an error string (see `reowolf_error_peek`) and returns -1
 
#[no_mangle]
 
pub unsafe extern "C" fn protocol_description_parse(
 
    pdl: *const u8,
 
    pdl_len: usize,
 
    out: *mut Arc<ProtocolDescription>,
 
) -> ErrorCode {
 
) -> *mut Arc<ProtocolDescription> {
 
    StoredError::tl_clear();
 
    match ProtocolDescription::parse(&*slice_from_parts(pdl, pdl_len)) {
 
        Ok(new) => {
 
            out.write(Arc::new(new));
 
            0
 
        }
 
        Ok(new) => Box::into_raw(Box::new(Arc::new(new))),
 
        Err(err) => {
 
            StoredError::tl_debug_store(&err);
 
            -1
 
            StoredError::tl_bytes_store(err.as_bytes());
 
            std::ptr::null_mut()
 
        }
 
    }
 
}
 

	
 
/// Destroys the given initialized protocol description and frees its resources.
 
#[no_mangle]
 
pub unsafe extern "C" fn protocol_description_destroy(pd: *mut Arc<ProtocolDescription>) {
 
    drop(Box::from_raw(pd))
 
}
 

	
 
/// Given an initialized protocol description, initializes `out` with a clone which can be independently created or destroyed.
 
#[no_mangle]
 
pub unsafe extern "C" fn protocol_description_clone(
 
    pd: &Arc<ProtocolDescription>,
 
    out: *mut Arc<ProtocolDescription>,
 
) {
 
    out.write(pd.clone());
 
) -> *mut Arc<ProtocolDescription> {
 
    Box::into_raw(Box::new(pd.clone()))
 
}
 

	
 
///////////////////// CONNECTOR //////////////////////////
 

	
 
/// Initializes `out` with a new connector using the given protocol description as its configuration.
 
/// The connector is assigned a random (internal) connector ID.
 
/// Allocates a new connector on the heap and returning a pointer,
 
/// given an initialized protocol description.
 
#[no_mangle]
 
pub unsafe extern "C" fn connector_new(pd: &Arc<ProtocolDescription>, out: *mut Connector) {
 
    connector_new_with_id(pd, random_connector_id(), out)
 
pub unsafe extern "C" fn connector_new(pd: &Arc<ProtocolDescription>) -> *mut Connector {
 
    connector_new_with_id(pd, random_connector_id())
 
}
 

	
 
/// Initializes `out` with a new connector using the given protocol description as its configuration.
 
/// The connector uses the given (internal) connector ID.
 
#[no_mangle]
 
pub unsafe extern "C" fn connector_new_with_id(
 
    pd: &Arc<ProtocolDescription>,
 
    cid: ConnectorId,
 
    out: *mut Connector,
 
) {
 
    out.write(Connector::new(Box::new(DummyLogger), pd.clone(), cid, 8))
 
) -> *mut Connector {
 
    let c = Connector::new(Box::new(DummyLogger), pd.clone(), cid, 8);
 
    Box::into_raw(Box::new(c))
 
}
 

	
 
/// Destroys the given initialized connector and frees its resources.
 
/// Destroys the given a pointer to the connector on the heap, freeing its resources.
 
/// Usable in {setup, communication} states.
 
#[no_mangle]
 
pub unsafe extern "C" fn connector_destroy(connector: Connector) {
 
    drop(connector)
 
pub unsafe extern "C" fn connector_destroy(connector: *mut Connector) {
 
    drop(Box::from_raw(connector))
 
}
 

	
 
/// Given an initialized connector in setup or connecting state,
 
/// - Creates a new directed port pair with logical channel putter->getter,
 
/// - adds the ports to the native component's interface,
 
/// - and returns them using the given out pointers.
 
/// Usable in {setup, communication} states.
 
#[no_mangle]
 
pub unsafe extern "C" fn connector_add_port_pair(
 
    connector: &mut Connector,
 
    out_putter: *mut PortId,
 
    out_getter: *mut PortId,
 
@@ -279,30 +274,26 @@ pub unsafe extern "C" fn connector_put_payload_cloning(
 
}
 

	
 
/// Convenience function combining the functionalities of
 
/// "payload_new" with "connector_put_payload".
 
#[no_mangle]
 
pub unsafe extern "C" fn connector_put_bytes(
 
    connector: &mut Connector,
 
    port: PortId,
 
    bytes_ptr: *const u8,
 
    bytes_len: usize,
 
) -> ErrorCode {
 
    StoredError::tl_clear();
 
    let payload: Payload = {
 
        let payload: *mut Payload = std::ptr::null_mut(); // uninitialized
 
        payload_new(bytes_ptr, bytes_len, payload); // initializes;
 
        payload.read()
 
    };
 
    match connector.put(port, payload) {
 
    let bytes = &*slice_from_parts(bytes_ptr, bytes_len);
 
    match connector.put(port, Payload::from(bytes)) {
 
        Ok(()) => 0,
 
        Err(err) => {
 
            StoredError::tl_debug_store(&err);
 
            -1
 
        }
 
    }
 
}
 

	
 
#[no_mangle]
 
pub unsafe extern "C" fn connector_get(connector: &mut Connector, port: PortId) -> ErrorCode {
 
    match connector.get(port) {
 
        Ok(()) => 0,
 
@@ -349,54 +340,54 @@ pub unsafe extern "C" fn connector_gotten_bytes(
 
        Ok(payload_borrow) => {
 
            let slice = payload_borrow.as_slice();
 
            len.write(slice.len());
 
            slice.as_ptr()
 
        }
 
        Err(err) => {
 
            StoredError::tl_debug_store(&err);
 
            std::ptr::null()
 
        }
 
    }
 
}
 

	
 
#[no_mangle]
 
pub unsafe extern "C" fn connector_gotten_payload(
 
    connector: &mut Connector,
 
    port: PortId,
 
) -> *const Payload {
 
    StoredError::tl_clear();
 
    match connector.gotten(port) {
 
        Ok(payload_borrow) => payload_borrow,
 
        Err(err) => {
 
            StoredError::tl_debug_store(&err);
 
            std::ptr::null()
 
        }
 
    }
 
}
 
// #[no_mangle]
 
// unsafe extern "C" fn connector_gotten_payload(
 
//     connector: &mut Connector,
 
//     port: PortId,
 
// ) -> *const Payload {
 
//     StoredError::tl_clear();
 
//     match connector.gotten(port) {
 
//         Ok(payload_borrow) => payload_borrow,
 
//         Err(err) => {
 
//             StoredError::tl_debug_store(&err);
 
//             std::ptr::null()
 
//         }
 
//     }
 
// }
 

	
 
///////////////////// PAYLOAD //////////////////////////
 
#[no_mangle]
 
pub unsafe extern "C" fn payload_new(
 
    bytes_ptr: *const u8,
 
    bytes_len: usize,
 
    out_payload: *mut Payload,
 
) {
 
    let bytes: &[u8] = &*slice_from_parts(bytes_ptr, bytes_len);
 
    out_payload.write(Payload::from(bytes));
 
}
 
// #[no_mangle]
 
// unsafe extern "C" fn payload_new(
 
//     bytes_ptr: *const u8,
 
//     bytes_len: usize,
 
//     out_payload: *mut Payload,
 
// ) {
 
//     let bytes: &[u8] = &*slice_from_parts(bytes_ptr, bytes_len);
 
//     out_payload.write(Payload::from(bytes));
 
// }
 

	
 
#[no_mangle]
 
pub unsafe extern "C" fn payload_destroy(payload: *mut Payload) {
 
    drop(Box::from_raw(payload))
 
}
 
// #[no_mangle]
 
// unsafe extern "C" fn payload_destroy(payload: *mut Payload) {
 
//     drop(Box::from_raw(payload))
 
// }
 

	
 
#[no_mangle]
 
pub unsafe extern "C" fn payload_clone(payload: &Payload, out_payload: *mut Payload) {
 
    out_payload.write(payload.clone())
 
}
 
// #[no_mangle]
 
// unsafe extern "C" fn payload_clone(payload: &Payload, out_payload: *mut Payload) {
 
//     out_payload.write(payload.clone())
 
// }
 

	
 
#[no_mangle]
 
pub unsafe extern "C" fn payload_peek_bytes(payload: &Payload, bytes_len: *mut usize) -> *const u8 {
 
    let slice = payload.as_slice();
 
    bytes_len.write(slice.len());
 
    slice.as_ptr()
 
}
 
// #[no_mangle]
 
// unsafe extern "C" fn payload_peek_bytes(payload: &Payload, bytes_len: *mut usize) -> *const u8 {
 
//     let slice = payload.as_slice();
 
//     bytes_len.write(slice.len());
 
//     slice.as_ptr()
 
// }
src/runtime/mod.rs
Show inline comments
 
@@ -205,35 +205,44 @@ pub struct SyncProtoContext<'a> {
 
}
 
////////////////
 
pub fn random_connector_id() -> ConnectorId {
 
    type Bytes8 = [u8; std::mem::size_of::<ConnectorId>()];
 
    let mut bytes = Bytes8::default();
 
    getrandom::getrandom(&mut bytes).unwrap();
 
    unsafe { std::mem::transmute::<Bytes8, ConnectorId>(bytes) }
 
}
 
pub fn would_block(err: &std::io::Error) -> bool {
 
    err.kind() == std::io::ErrorKind::WouldBlock
 
}
 
impl<T: std::cmp::Ord> VecSet<T> {
 
    fn iter(&self) -> std::slice::Iter<T> {
 
        self.vec.iter()
 
    }
 
    fn contains(&self, element: &T) -> bool {
 
        self.vec.binary_search(element).is_ok()
 
    }
 
    fn new(mut vec: Vec<T>) -> Self {
 
        vec.sort();
 
        vec.dedup();
 
        Self { vec }
 
    }
 
    fn contains(&self, element: &T) -> bool {
 
        self.vec.binary_search(element).is_ok()
 
    }
 
    fn insert(&mut self, element: T) -> bool {
 
        match self.vec.binary_search(&element) {
 
            Ok(_) => false,
 
            Err(index) => {
 
                self.vec.insert(index, element);
 
                true
 
            }
 
        }
 
    }
 
    fn iter(&self) -> std::slice::Iter<T> {
 
        self.vec.iter()
 
    }
 
}
 
impl PortInfo {
 
    fn firing_var_for(&self, port: PortId) -> FiringVar {
 
        FiringVar(match self.polarities.get(&port).unwrap() {
 
            Getter => port,
 
            Putter => *self.peers.get(&port).unwrap(),
 
        })
 
    }
 
}
 
impl IdManager {
 
    fn new(connector_id: ConnectorId) -> Self {
 
        Self {
0 comments (0 inline, 0 general)