These are chat archives for rust-lang/rust

21st
Aug 2017
BalaB
@BbalajiSg_twitter
Aug 21 2017 03:50
I created a crate using
cargo new crypto-<name>
after that I changed my mind saying instead of lib, let it be a executable
So, whats the cargo command to change from lib to executable (—bin )?
Restioson
@Restioson
Aug 21 2017 04:33
I think just rename lib.rs to main.rs
BalaB
@BbalajiSg_twitter
Aug 21 2017 05:06
yes that the only way I could see for now @Restioson
Thanks buddy
Restioson
@Restioson
Aug 21 2017 05:08
Np
Restioson
@Restioson
Aug 21 2017 06:11
@vorner about the instructions sending - you suggested an enum right?
What about if there was a macro which defined a tuple/struct for those arguments, and then you send that across the wire to make it run.
It'd define a function like
This message was deleted
Essentially the function would just send the right data across the wire so you could call it normally
Dylan McKay
@dylanmckay
Aug 21 2017 06:27

I think something like this would be your best bet @Restioson

#[cfg(feature = "host")]
fn main() {
    let slaves = Vec::new();
    // add slaves

    // this function will be only run on the slaves
    fn do_work() {
        for i in 0..10000 {
            // do something complex
        }
    }
    dispatch(&slaves[0], do_work);
}

// Used by the host to dispatch machine code to the slave
fn dispatch(slave: &Slave, f: fn()) {
    let mc = self::get_machine_code(f);
    slave.send_command(Command::run(mc));
}

fn get_machine_code(f: fn()) -> Vec<u8> {
    // read bytes from the function pointer
    // stop when we read a 'RET' instruction, which is always the same
    // bit pattern
}

#[cfg(feature = "target")]
fn main() {
    let listener = { ... };

    loop {
        if let Some(command) = listener.receive() {
            match command {
                Command::Run(machine_code) => {
                    store_program_memory(machine_code);
                    jump to flashed machine code
                },
            }
        }
    }
}

it'd be really hard/impossible? to disable globals for your function, so it's easier to just support them and load the same globals to all masters/slaves. with this setup, the master and the slaves will be running the same program, just with different main functions

if you don't want to muck around with machine code, you could always just pass a pointer to a function through to the slaves, but then you need to guarantee that the function is at the same address in both executables

one way of doing this could be to include the main functions for both the master and slaves, with a simply if master { master_main() } else { slave_main() }

this of course requires that the build is reproducible, which in general it very likely is, especially for a small program like this

Denis Lisov
@tanriol
Aug 21 2017 06:31
@Restioson Do you compile the same code for both the host CPU (probably x86/amd64) and AVR? Or do you have one AVR chip flashing another?
Restioson
@Restioson
Aug 21 2017 07:21
Yep
One chip flashes another
I made a mockup of a macro to define a routine
It's bad and doesn't compile (I wrote it on my phone)
routine!(name(arg1: T, arg2: Y...) -> R) {
...
});

/* expands to */

static nameClosure = |arg1: T, arg2: Y... | {
  ... 
} 

struct Name(arg1: T...) 

fn name(arg1: T, arg2: Y...) {
    let args = Name(arg1, arg2...);
    // send cmd to callbac
} 

fn nameCallback(args: Name) {
    let (arg1, arg2...) = args; // Destructure
    spi::send_when_ready(closure());
} 

// call like this
name((args));
I'd have to replace name closure with a function
@dylanmckay yeah, that's what I was thinking. Bootloader can take whether is slave or master over spi
lemonxah
@lemonxah
Aug 21 2017 09:25
does nightly touch stable feautres?
in otherwords if we use nightly because another lib is using it to be able to use that lib, would nightly break something that has been marked as stable?
or is all stable features still stable in all nightlies?
Jonas Platte
@jplatte
Aug 21 2017 09:45
@lemonxah Things that are stable should not break in nightly. There's of course a higher likelyhood of bugs in nightly than in stable though.
StelarCF
@StelarCF
Aug 21 2017 16:02
if I have an object with one generic argument and want to give it as an argument in Arc<Mutex<>> to a trait is it possible to have it ignore the generic argument in some way?
the way you can have an Arc<Mutex<SomeTrait>> (or at least Box<SomeTrait>)
because I don't want to have generic type parameters in my trait or I can't make it into an object that I can hold...
Zakarum
@omni-viral
Aug 21 2017 16:03
Your SomeTrait have parameters?
StelarCF
@StelarCF
Aug 21 2017 16:03
I don't have a Trait
I have a struct
that has one type parameter (sorry for linesplitting)
Zakarum
@omni-viral
Aug 21 2017 16:04
Ok. You struct isn't a proper type without it's type parameter
Vec isn't a type. Vec<u8> is
StelarCF
@StelarCF
Aug 21 2017 16:04
yeah, but is there no way to avoid being boxed in by generic parameters?
here's my situation in code
pub struct GraphicObject<R> where R: Resources {
    pub vertices: (gfx::handle::Buffer<R, Vertex>, Slice<R>),
    pub model_matrix: Matrix4<f32>,
    pub material: Material<R>,
}
pub trait Scene {
...
    fn receive_graphical_objects<R>(&mut self, g: Arc<Mutex<HashMap<String, GraphicObject<R>>>>) -> Result<(), &'static str> where R: gfx::Resources { Ok(()) }
...
}
pub struct Engine {
...
    queued_scene: Option<Box<Scene>>,
    scene: Option<Box<Scene>>,
...
}
resulting error
65 |     queued_scene: Option<Box<Scene>>,
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `engine::scene::Scene` cannot be made into an object
Jonas Platte
@jplatte
Aug 21 2017 16:07
@StelarCF This means that the Scene trait is not object-safe.
StelarCF
@StelarCF
Aug 21 2017 16:07
I KNOW
Jonas Platte
@jplatte
Aug 21 2017 16:07
Do you really want Scenes with different Resource types?
StelarCF
@StelarCF
Aug 21 2017 16:08
I don't, but I don't know how to avoid needing that type argument there
because GraphicObject wants a type argument, and I need to supply it
Zakarum
@omni-viral
Aug 21 2017 16:08
If you need to be able to store your Struct<T> in some plays for any T you have to use TraitObject or propagate type parameter
StelarCF
@StelarCF
Aug 21 2017 16:08
and either I force it to be a certain implementor...
Jonas Platte
@jplatte
Aug 21 2017 16:08
You can't. You just make your Engine struct generic over the resource type and replace Box<Scene> with Scene<R>.
StelarCF
@StelarCF
Aug 21 2017 16:08
propagate type parameter?
Jonas Platte
@jplatte
Aug 21 2017 16:09
Yeah
StelarCF
@StelarCF
Aug 21 2017 16:09
ugh
that's an idea but yet another thing I want to avoid -_-
I think I'm going to and try just decoupling it more
Jonas Platte
@jplatte
Aug 21 2017 16:11
I think it's just how gfx works, it's probably best to just do the same thing that it does everywhere and make your stuff generic over Resources (whatever exactly that even means...)
Zakarum
@omni-viral
Aug 21 2017 16:11
@StelarCF I see you're using gfx.
The R in gfx depends on your backend
Jonas Platte
@jplatte
Aug 21 2017 16:11
Ah, it's for backend abstraction. That makes sense.
Zakarum
@omni-viral
Aug 21 2017 16:12
If you're not makeing backend-agnostic library you can just make type Resource = yourgfxbackend::Resource
And use it everywhere
In place of R
If you want serveral backends you may put this type alias declaration under #[cfg(feature)] with each backend imports
StelarCF
@StelarCF
Aug 21 2017 16:34
well I'm trying to be backend agnostic so -_-
Zakarum
@omni-viral
Aug 21 2017 17:07
Then you have no other option. Put R: Resources where needed
Backed aware user will supply it
You may be sure that all Rs are the same at least