doc/wg/core/notes/core-notes-2021-06-04.md
Attending:
print_tock_memory_usage.py.
In this function, we have tx.buffer.take().map, and inside this .map() we
have a for loop that performs .iter() and .enumerate(). Currently, the
function is 284 bytes, and the total kernel size is around 174 kB. The
question is, is there any way we can rewrite this boxed portion of code to
maintain functionality but at the same time reduce code space..map.
Instead, we take the buffer and simply unwrap it. With this, the size of the
send function increased by 8 bytes and the size of the embedded data by 6
bytes, but the function tock_cells decreased by 14 bytes, resulting in no
net change..enumerate call from the loop. We
replaced the .enumerate call with a separate counter we incremented
manually. This did not produce an overall change in the kernel size or
embedded data size. We think rustc already optimized .enumerate().buffer.len() function is called repeatedly. We weren't sure whether the
compiler optimized it. We wanted to test whether the compiler actually had
code overhead for calling buffer.len() many times. There was no change in
kernel size or data size, so we concluded it's already optimized by rustc..copy_from_slice().
copy_from_slice has the same functionality as the for loop. However, we had
to split it into two cases based on the size of the buffer. What's
interesting is that the size of send increased by 4 bytes overall, however
the size of embedded data across the kernel decreased by 28 bytes. Under the
hood, this function called core::ops::Range, which increased by 40 bytes.
Therefore there is an overall change in kernel size of 16 bytes.rustc may change optimization settings in the
future, or it may be different on another board. For future work, it would be
good to replicate this experiment with a different board.send closure 284
bytes in the first place? For the first one, you have method original of 284
bytes, but what are the source lines these are attributed at? Can you trace
where the code came from in the source code? Maybe the cost came from some
other code?copy_from_slice call from for else range takes 20 bytes compared to 36
bytes. However, in the assembly, we found that this was done twice, resulting
in the function being 4 bytes larger overall.app.remaining. Try to do the following: create variables
app_remaining = app.remaining before the closure and then use these
variables which copy content from the closure manually and see how that
affects the cost. If these are primitive data types maybe copying these
variables may be more efficient than copying the whole struct which contains
something you don't use inside the closure.unsafe.
The current proposal is for read-write allows and read-only allows, userspace
libraries must not access those buffers, and we'll have a separate system
call for buffers that allow concurrent access between userspace and the
kernel with its own rules for how they access it. Do people think that's the
right summary or want to talk about some of the complexities?libtock-rs' design. If we say
userspace MUST not access the buffer, that allows us to design libtock-rs
so that you cannot -- in safe Rust -- access the buffer after it has been
allowed. Practically speaking, that means capsules cannot ask apps to do
that, because apps written in Rust that try to use the capsules will be
unable to do so. The other side is capsules must be tolerant of that anyway
because a malicious app might do so anyway. We would consider an app
accessing data that Allow says it can't access to be a bug, and we cannot
have the kernel rely on that for correct function, but it may exist from a
threat modelling standpoint.libtock-c and thought about if the APIs there
make this at all intuitive? Is there a way to make it intuitive?libtock-c's side.libtock-c is not doing this
correctly.libtock-c code, if you
call send, it does an Allow to give the buffer to the kernel, it does a
subscribe, it does a command, it does a yield, it doesn't do another Allow to
get the buffer back. That's a pretty simple thing to go through.libtock-c, I think the
rule about not using the buffer is not clear. I did not follow this rule
because I did not know about it.get_pointer or something like
that. Can create an error if somebody does it wrong.