doc/wg/core/notes/core-notes-2022-06-03.md
Attendees:
LeasableBuffer abstraction we spoke about last week as part of the DMA
buffer. Hopefully there will be more news and actual code output next week.VolatileCell that Alyssa had brought up. Alyssa,
I hope you're happy with how that ended up?LeasableBufferLeasableBuffer. I'd like to propose a change.add_data. To give some background. Digest has 3 traits. There's
adding data to something you're going to digest -- a mechanism for taking a
large piece of data and turning it into a small piece of data with status and
integrity guarantees. It takes a LeasableBuffer. The idea is you could add
some big thing like a process image, and use the LeasableBuffer to limit
the size of stuff you're digesting over without messing with slices. As
Hudson pointed out, technically the implementation can use the whole slice,
so it doesn't provide privacy, but it's an easy way to couple the three
values down: slice, start, and end.Ok, you get a value back of how much is going to be
digested. When you get a completion callback,LeasableBuffer back, it gives you the actual
slice. My thought is that one of these two things should be true: either
add_data should operate on the entire active region of the LeasableBuffer
or it's an error, so Ok should be a unit type, or add_data_done should
pass back the LeasableBuffer with the active region being the data
remaining.LeasableBuffer is weird -- tracking
LeasableBuffer state and replicating it repeatedly.LeasableBuffer. The first time I saw similar code, I was
surprised to see you were calling reset or transmutting it back into a
mutable slice in the peripheral driver, while I was passing the
LeasableBuffer back. That is definitely a part which is underspecified in
the current API. I don't have an idea for what I think a sensible API would
look like. Closing in on the discussion we had last week on a potential DMA
buffer, we may want to extend this API to cover the functionality of
LeasableBuffer, as it is solving a lot of these issues by its design. I can
go into more details if you'd like, but we could continue discussing the
current LeasableBuffer too.reset on the buffer and our HILs don't set a clear
precedent for how they should be reset. The second problem is that often
when you're using LeasableBuffer, you also want to be tracking how much of
the buffer that was initially shared has been consumed, and it's not clear
whether LeasableBuffer should be updated to track the amount of the buffer
that has been consumed or whether LeasableBuffer is just for the higher
layer to specify the subset of the buffer it wants to share.LeasableBuffer as a mechanism just for the client to limit what
region of the buffer is designated for the peripheral to operate on. I fear
that if we are also using it as a mechanism to return feedback on what the
peripheral has actually done, it will get more confusing because you have
influences from both sides, which are fundamentally different aspects of the
implementation. On one hand, you want to pass a buffer which is just an
implementation detail of us using static mutable slices which we cannot slice
easily, and on the other we want to pass some feedback on what data the
operation has operated on. I don't feel comfortable mixing these two
concepts. It also has the disadvantage of losing track of what you originally
passed to the peripheral.add_data doesn't return a usize, and an
Ok then as well as a callback which indicates a success means that the
entire active region of the LeasableBuffer as passed was added. You can't
do like a partial add and return Ok, which is what happens now. That way
it's then fine to pass back the slice or LeasableBuffer, that's less
important because from the caller's standpoint you can do either one from
either.Ok and get a type, and when I
get the callback, the LeasableBuffer tells me how much I have left, that is
valid. This data structure indicates how much is remaining. I kind of prefer
the first approach -- a successful operation means the entire active region
was added -- because it simplifies the client code. It forces a state machine
at the bottom for hardware that can only digest a certain number of things in
a particular interrupt, for instance OpenTitan, but it means that you don't
have to have that state machine a layer above.malloc. I pass in a list, and it gives me a list back, which is what it
didn't do. That seems like a valid use of the list. Regardless, an easy way
to dodge this without adding types is to say that an Ok means that it did
the whole active region of the LeasableBuffer, and the low level driver
just needs a state machine.add_data and it gives Ok but it
can't process the whole buffer, when you signal the error case in the
callback you tell it how much was processed?