11#include "../tock.h"
22
3+ #define STREAMING_PROCESS_SLICE_HEADER_LEN 8
4+
35typedef struct {
4- uint8_t * app_buffer_ptr ;
5- size_t app_buffer_size ;
66 uint32_t driver ;
77 uint32_t allow ;
8+ uint8_t * app_buffer_ptr ;
9+ size_t app_buffer_size ;
10+ bool app_buffer_is_b ;
811} streaming_process_slice_state_t ;
912
1013// Initialize a "streaming process slice" read-write allow slot
1114//
12- // This method allows a userspace buffer into a "streaming process
13- // slice" allow slot, implementing its atomic-swap semantics and
14- // header layout. The streaming process slice abstraction allows a
15- // userspace process to lossessly receive data from a kernel
16- // capsule. This is done by maintaining two buffers, where at any time
17- // one of which is owned by the kernel (for writing new, incoming data
18- // into) and one by the application, to process received data. These
19- // buffers are atomically swapped by the application, upon receipt of
20- // a signal that some data has been inserted into the kernel-owned
21- // buffer (such as an upcall).
15+ // This method allows a userspace buffer into a "streaming process slice" allow
16+ // slot, implementing its atomic-swap semantics and header layout. The streaming
17+ // process slice abstraction allows a userspace process to lossessly receive
18+ // data from a kernel capsule. This is done by maintaining two buffers, where at
19+ // any time one of which is owned by the kernel (for writing new, incoming data
20+ // into) and one by the application, to process received data. These buffers are
21+ // atomically swapped by the application, upon receipt of a signal that some
22+ // data has been inserted into the kernel-owned buffer (such as an upcall).
23+ //
24+ // This method abstracts this interface by consuming two buffers, owned by the
25+ // application and kernel respectively. It tracks all necessary state in the
26+ // `streaming_process_slice_state_t` object. This struct is initialized by this
27+ // method.
2228//
23- // This method abstracts this interface by consuming one buffer and
24- // splitting it into two halves, owned by the application and kernel
25- // respectively. It tracks all necessary state in the
26- // `streaming_process_slice_state_t` object. For this to work, the
27- // passed buffer must be able to hold at least two streaming process
28- // slice headers (8 byte each), i.e., it must be at least 16 bytes
29- // long.
29+ // The passed buffers must be each be able to hold at least the streaming
30+ // process slice headers (`STREAMING_PROCESS_SLICE_HEADER_LEN` bytes), in
31+ // addition to any payload.
3032//
31- // In case of an error while allowing the kernel-owned buffer to the
32- // specified driver and read-write allow slot, this function converts
33- // this error-status into a returncode using
34- // `tock_status_to_returncode` and returns it to the caller. When this
35- // method returns `RETURNCODE_SUCCESS`, the passed buffer is assumed
36- // to be owned by this `streaming_process_slice_state_t` and must not
37- // be used until after a successful call to
38- // `streaming_process_slice_deinit`. When the buffer is of
39- // insufficient size, it returns `RETURNCODE_ESIZE`.
33+ // In case of an error while allowing the kernel-owned buffer to the specified
34+ // driver and read-write allow slot, this function converts this error-status
35+ // into a returncode using `tock_status_to_returncode` and returns it to the
36+ // caller. When this method returns `RETURNCODE_SUCCESS`, the passed buffers are
37+ // assumed to be owned by this `streaming_process_slice_state_t` and must not be
38+ // used until after a successful call to `streaming_process_slice_deinit`. When
39+ // either buffer is of insufficient size, it returns `RETURNCODE_ESIZE` and does
40+ // not perform any allow operation or initialize the state reference.
4041returncode_t streaming_process_slice_init (
4142 streaming_process_slice_state_t * state ,
4243 uint32_t driver ,
4344 uint32_t allow ,
44- void * buffer ,
45- size_t size );
45+ void * buffer_a ,
46+ size_t size_a ,
47+ void * buffer_b ,
48+ size_t size_b );
4649
4750// Swap kernel- for app-owned buffer and get received payload
4851//
49- // This method atomically swaps the kernel-owned and application-owned
50- // halves of the streaming process slice. This function will reset the
52+ // This method atomically swaps the kernel-owned and application-owned buffers
53+ // backing this streaming process slice. This function will reset the
5154// application-owned buffers header, applying any flags set in the
52- // `streaming_process_slice_state_t` and setting the write offset to
53- // `0`.
55+ // `streaming_process_slice_state_t` and setting the write offset to `0`.
5456//
55- // Following the swap operation, when returning `RETURNCODE_SUCCESS`,
56- // it provides the buffer's payload and any kernel-set flags to the
57- // caller through the `buffer`, `size`, and `exceeded` arguments
58- // respectively. Callers must either provide pointers to variables for
59- // these values, or set them to `NULL` in case they are not interested
60- // in any given value.
57+ // Following the swap operation, when returning `RETURNCODE_SUCCESS`, it
58+ // provides the buffer's payload and any kernel-set flags to the caller through
59+ // the `buffer`, `size`, and `exceeded` arguments respectively. Callers must
60+ // either provide pointers to variables for these values, or set them to `NULL`
61+ // in case they are not interested in any given value.
6162//
6263// This function forwards any error from the underlying `allow_readwrite`
6364// operation in its return value. In case of a return value other than
@@ -71,15 +72,21 @@ returncode_t streaming_process_slice_get_and_swap(
7172
7273// Deinitialize an initialized `streaming_process_slice_state_t`
7374//
74- // This function reconstructs the passed into `streaming_process_slice_init` and
75- // returns it through the `buffer` and `size` arguments (if not set to `NULL`
76- // respectively).
75+ // This function returns the buffers passed into `streaming_process_slice_init`
76+ // through the `buffer_a`, `size_a`, `buffer_b` and `size_b` arguments (if not
77+ // set to `NULL` respectively). It ensures that the `buffer_a` and `size_a`
78+ // arguments passed to `streaming_process_slice_init` match those of `buffer_a`
79+ // and `size_a` for this function, i.e., it will not swap `buffer_a` for
80+ // `buffer_b`, regardless of the number of calls to
81+ // `streaming_process_slice_get_and_swap`.
7782//
7883// This function forwards any error from the underlying `allow_readwrite`
7984// operation in its return value. In case of a return value other than
8085// `RETURNCODE_SUCCESS`, any values returned in `buffer`, `size` and `exceeded`
8186// must not be considered valid.
8287returncode_t streaming_process_slice_deinit (
8388 streaming_process_slice_state_t * state ,
84- uint8_t * * buffer ,
85- size_t * size );
89+ uint8_t * * buffer_a ,
90+ size_t * size_a ,
91+ uint8_t * * buffer_b ,
92+ size_t * size_b );
0 commit comments