Skip to content

Commit

Permalink
WIP - ufo vectors pass their tests with the rust backend! Happy Happy…
Browse files Browse the repository at this point in the history
… Happy!
  • Loading branch information
electroCutie committed Aug 15, 2021
1 parent e57d83f commit 1382073
Show file tree
Hide file tree
Showing 19 changed files with 810 additions and 109 deletions.
112 changes: 55 additions & 57 deletions ufos/rust/ufos_c/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use std::fmt::Debug;
use std::sync::{Arc, RwLockWriteGuard};

use anyhow::Result;

use libc::c_void;
use ufos_core::{UfoCoreConfig, UfoObjectConfigPrototype, UfoPopulateError, WrappedUfoObject, UfoObject};


use ufos_core::{
UfoCoreConfig, UfoObject, UfoObjectConfigPrototype, UfoPopulateError, WrappedUfoObject,
};

macro_rules! opaque_c_type {
($wrapper_name:ident, $wrapped_type:ty) => {
Expand Down Expand Up @@ -62,20 +63,21 @@ pub struct UfoCore {
opaque_c_type!(UfoCore, Arc<ufos_core::UfoCore>);

type UfoPopulateData = *mut c_void;
type UfoPopulateCallout = extern "C" fn(UfoPopulateData, libc::size_t, libc::size_t, *mut libc::c_uchar) -> i32;
type UfoPopulateCallout = extern "C" fn(UfoPopulateData, usize, usize, *mut libc::c_uchar) -> i32;

impl UfoCore {
#[no_mangle]
pub unsafe extern "C" fn ufo_new_core(
writeback_temp_path: *const libc::c_char,
low_water_mark: libc::size_t,
high_water_mark: libc::size_t,
low_water_mark: usize,
high_water_mark: usize,
) -> Self {
std::panic::catch_unwind(|| {
let wb = std::ffi::CStr::from_ptr(writeback_temp_path)
.to_str().expect("invalid string")
.to_str()
.expect("invalid string")
.to_string();

let mut low_water_mark = low_water_mark;
let mut high_water_mark = high_water_mark;

Expand Down Expand Up @@ -108,28 +110,32 @@ impl UfoCore {
}

#[no_mangle]
pub extern "C" fn ufo_get_by_address(&self, ptr: *mut libc::c_void) -> UfoObj{
pub extern "C" fn ufo_get_by_address(&self, ptr: *mut libc::c_void) -> UfoObj {
std::panic::catch_unwind(|| {
self.deref()
.and_then( |core| {
let ufo = core
.get_ufo_by_address(ptr as usize).ok()?;
Some(UfoObj::wrap(ufo))
})
.unwrap_or_else(UfoObj::none)
}).unwrap_or_else(|_| UfoObj::none())
.and_then(|core| {
let ufo = core
.get_ufo_by_address(ptr as usize)
.expect("UFO lookup failed");
Some(UfoObj::wrap(ufo))
})
.unwrap_or_else(UfoObj::none)
})
.unwrap_or_else(|_| UfoObj::none())
}

#[no_mangle]
pub extern "C" fn ufo_address_is_ufo_object(&self, ptr: *mut libc::c_void) -> bool{
pub extern "C" fn ufo_address_is_ufo_object(&self, ptr: *mut libc::c_void) -> bool {
std::panic::catch_unwind(|| {
self.deref()
.and_then( |core| {
core.get_ufo_by_address(ptr as usize).ok()?;
Some(true)
})
.unwrap_or(false)
}).unwrap_or(false)
.and_then(|core| {
core.get_ufo_by_address(ptr as usize)
.expect("UFO lookup failed");
Some(true)
})
.unwrap_or(false)
})
.unwrap_or(false)
}

#[no_mangle]
Expand All @@ -152,26 +158,19 @@ impl UfoCore {
read_only,
);

let callback_data_int = callback_data as usize;
let callback_data_int = callback_data as usize;
let populate = move |start, end, to_populate| {
let ret = populate(
callback_data_int as *mut c_void,
start,
end,
to_populate,
);
let ret = populate(callback_data_int as *mut c_void, start, end, to_populate);

if ret != 0 {
Err(UfoPopulateError)
}else{
} else {
Ok(())
}
};
let r = self
.deref()
.map(move |core| {
core.allocate_ufo(prototype.new_config(ct, Box::new(populate)))
});
.map(move |core| core.allocate_ufo(prototype.new_config(ct, Box::new(populate))));
match r {
Some(Ok(ufo)) => UfoObj::wrap(ufo),
_ => UfoObj::none(),
Expand All @@ -180,7 +179,6 @@ impl UfoCore {
.unwrap_or_else(|_| UfoObj::none())
}


#[no_mangle]
pub extern "C" fn ufo_new_with_prototype(
&self,
Expand All @@ -192,16 +190,11 @@ impl UfoCore {
std::panic::catch_unwind(|| {
let callback_data_int = callback_data as usize;
let populate = move |start, end, to_populate| {
let ret = populate(
callback_data_int as *mut c_void,
start,
end,
to_populate,
);
let ret = populate(callback_data_int as *mut c_void, start, end, to_populate);

if ret != 0 {
Err(UfoPopulateError)
}else{
} else {
Ok(())
}
};
Expand All @@ -226,7 +219,6 @@ pub struct UfoPrototype {
}
opaque_c_type!(UfoPrototype, UfoObjectConfigPrototype);


impl UfoPrototype {
#[no_mangle]
pub extern "C" fn ufo_new_prototype(
Expand All @@ -253,7 +245,7 @@ impl UfoPrototype {
}

#[no_mangle]
pub extern "C" fn ufo_free_prototype(self){}
pub extern "C" fn ufo_free_prototype(self) {}
}

#[repr(C)]
Expand All @@ -266,13 +258,13 @@ opaque_c_type!(UfoObj, WrappedUfoObject);
impl UfoObj {
fn with_ufo<F, T, E>(&self, f: F) -> Option<T>
where
F: FnOnce(RwLockWriteGuard<UfoObject>) -> Result<T, E>
F: FnOnce(RwLockWriteGuard<UfoObject>) -> Result<T, E>,
E: Debug,
{
self.deref()
.and_then(|ufo| {
ufo.write().ok()
.map(f)?.ok()
})
self.deref().map(|ufo| {
let locked_ufo = ufo.write().expect("unable to lock UFO");
f(locked_ufo).expect("Function call failed")
})
}

#[no_mangle]
Expand All @@ -290,7 +282,7 @@ impl UfoObj {
pub extern "C" fn ufo_header_ptr(&self) -> *mut std::ffi::c_void {
std::panic::catch_unwind(|| {
self.with_ufo(|ufo| Ok::<*mut c_void, ()>(ufo.header_ptr()))
.unwrap_or_else(|| std::ptr::null_mut())
.unwrap_or_else(|| std::ptr::null_mut())
})
.unwrap_or_else(|_| std::ptr::null_mut())
}
Expand All @@ -299,7 +291,7 @@ impl UfoObj {
pub extern "C" fn ufo_body_ptr(&self) -> *mut std::ffi::c_void {
std::panic::catch_unwind(|| {
self.with_ufo(|ufo| Ok::<*mut c_void, ()>(ufo.body_ptr()))
.unwrap_or_else(|| std::ptr::null_mut())
.unwrap_or_else(|| std::ptr::null_mut())
})
.unwrap_or_else(|_| std::ptr::null_mut())
}
Expand All @@ -308,10 +300,16 @@ impl UfoObj {
pub extern "C" fn ufo_free(self) {
std::panic::catch_unwind(|| {
self.deref()
.and_then(|ufo| ufo.write().ok()?.free().ok())
.map(|w| w.wait())
.unwrap_or(())
}).unwrap_or(())
.map(|ufo| {
ufo.write()
.expect("unable to lock UFO")
.free()
.expect("unable to free UFO")
})
.map(|w| w.wait())
.unwrap_or(())
})
.unwrap_or(())
}

#[no_mangle]
Expand All @@ -328,4 +326,4 @@ pub extern "C" fn ufo_begin_log() {
.timestamp(stderrlog::Timestamp::Millisecond)
.init()
.unwrap();
}
}
6 changes: 4 additions & 2 deletions ufos/src/ufos.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ SEXP ufo_initialize() {
if (!__framework_initialized) {
__framework_initialized = 1;

// ufo_begin_log(); // very verbose rust logging

// Actual initialization
size_t high = 2l * 1024 * 1024 * 1024;
size_t low = 1l * 1024 * 1024 * 1024;
Expand Down Expand Up @@ -82,6 +84,7 @@ void* __ufo_alloc(R_allocator_t *allocator, size_t size) {
source->population_function
);


if (ufo_is_error(&object)) {
Rf_error("Could not create UFO");
}
Expand Down Expand Up @@ -140,8 +143,7 @@ int __vector_will_be_scalarized(SEXPTYPE type, size_t length) {
}

void __prepopulate_scalar(SEXP scalar, ufo_source_t* source) {
source->population_function(DATAPTR(scalar), 0, source->vector_size,
source->data);
source->population_function(source->data, 0, source->vector_size, DATAPTR(scalar));
}

void __reset_vector(SEXP vector) {
Expand Down
9 changes: 6 additions & 3 deletions ufos/src/ufos.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#pragma once

//#include "mappedMemory/userfaultCore.h"
#include "ufos_c.h"
// #include "ufos_c.h"

#include <R.h>
#include <Rinternals.h>

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

typedef enum {
UFO_CHAR = CHARSXP,
Expand All @@ -19,12 +20,14 @@ typedef enum {
UFO_VEC = VECSXP,
} ufo_vector_type_t;

typedef int32_t (*UfoPopulateCallout)(void*, uintptr_t, uintptr_t, unsigned char*);

// Function types for ufo_source_t
typedef void (*ufo_destructor_t)(UfoPopulateData*);
typedef void (*ufo_destructor_t)(void*);

// Source definition
typedef struct {
UfoPopulateData data;
void* data;
UfoPopulateCallout population_function;
ufo_destructor_t destructor_function;
ufo_vector_type_t vector_type;
Expand Down
1 change: 1 addition & 0 deletions ufoseq/include/ufos.h
1 change: 0 additions & 1 deletion ufoseq/include/ufos_c.h

This file was deleted.

3 changes: 2 additions & 1 deletion ufovectors/.vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"compilerPath": "/usr/bin/gcc",
"cStandard": "gnu17",
"cppStandard": "gnu++14",
"intelliSenseMode": "linux-gcc-x64"
"intelliSenseMode": "linux-gcc-x64",
"configurationProvider": "ms-vscode.cmake-tools"
}
],
"version": 4
Expand Down
3 changes: 3 additions & 0 deletions ufovectors/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@

## Installation

## Test
R CMD check ./

## Getting started
Loading

0 comments on commit 1382073

Please sign in to comment.