• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #pragma once
15 
16 #include "base/export.h"
17 
18 #include <stdbool.h>
19 #include <stdint.h>
20 
21 #define RING_BUFFER_SHIFT 11
22 #define RING_BUFFER_SIZE (1 << RING_BUFFER_SHIFT)
23 #define NUM_CONFIG_FIELDS 32
24 
25 // Single producer/consumer ring buffer struct that can be shared
26 // between host and guest as-is.
27 struct ring_buffer {
28     uint32_t host_version;
29     uint32_t guest_version;
30     uint32_t write_pos; // Atomically updated for the consumer
31     uint32_t unused0[13]; // Separate cache line
32     uint32_t read_pos; // Atomically updated for the producer
33     uint32_t read_live_count;
34     uint32_t read_yield_count;
35     uint32_t read_sleep_us_count;
36     uint32_t unused1[12]; // Separate cache line
37     uint8_t buf[RING_BUFFER_SIZE];
38     uint32_t state; // An atomically updated variable from both
39                     // producer and consumer for other forms of
40                     // coordination.
41     uint32_t config[NUM_CONFIG_FIELDS];
42 };
43 
44 void ring_buffer_init(struct ring_buffer* r);
45 
46 // Writes or reads step_size at a time. Sets errno=EAGAIN if full or empty.
47 // Returns the number of step_size steps read.
48 long ring_buffer_write(
49     struct ring_buffer* r, const void* data, uint32_t step_size, uint32_t steps);
50 long ring_buffer_read(
51     struct ring_buffer* r, void* data, uint32_t step_size, uint32_t steps);
52 // Like ring_buffer_write / ring_buffer_read, but merely advances the counters
53 // without reading or writing anything. Returns the number of step_size steps
54 // advanced.
55 long ring_buffer_advance_write(
56     struct ring_buffer* r, uint32_t step_size, uint32_t steps);
57 long ring_buffer_advance_read(
58     struct ring_buffer* r, uint32_t step_size, uint32_t steps);
59 
60 // If we want to work with dynamically allocated buffers, a separate struct is
61 // needed; the host and guest are in different address spaces and thus have
62 // different views of the same memory, with the host and guest having different
63 // copies of this struct.
64 struct ring_buffer_view {
65     uint8_t* buf;
66     uint32_t size;
67     uint32_t mask;
68 };
69 
70 // Convenience struct that holds a pointer to a ring along with a view.  It's a
71 // common pattern for the ring and the buffer of the view to be shared between
72 // two entities (in this case, usually guest and host).
73 struct ring_buffer_with_view {
74     struct ring_buffer* ring;
75     struct ring_buffer_view view;
76 };
77 
78 // Calculates the highest power of 2 so that
79 // (1 << shift) <= size.
80 uint32_t ring_buffer_calc_shift(uint32_t size);
81 
82 // Initializes ring buffer with view using |buf|. If |size| is not a power of
83 // two, then the buffer will assume a size equal to the greater power of two
84 // less than |size|.
85 void ring_buffer_view_init(
86     struct ring_buffer* r,
87     struct ring_buffer_view* v,
88     uint8_t* buf,
89     uint32_t size);
90 
91 void ring_buffer_init_view_only(
92     struct ring_buffer_view* v,
93     uint8_t* buf,
94     uint32_t size);
95 
96 // Read/write functions with the view.
97 long ring_buffer_view_write(
98     struct ring_buffer* r,
99     struct ring_buffer_view* v,
100     const void* data, uint32_t step_size, uint32_t steps);
101 long ring_buffer_view_read(
102     struct ring_buffer* r,
103     struct ring_buffer_view* v,
104     void* data, uint32_t step_size, uint32_t steps);
105 
106 // Usage of ring_buffer as a waitable object.
107 // These functions will back off if spinning too long.
108 //
109 // if |v| is null, it is assumed that the statically allocated ring buffer is
110 // used.
111 //
112 // Returns true if ring buffer became available, false if timed out.
113 bool ring_buffer_wait_write(
114     const struct ring_buffer* r,
115     const struct ring_buffer_view* v,
116     uint32_t bytes,
117     uint64_t timeout_us);
118 bool ring_buffer_wait_read(
119     const struct ring_buffer* r,
120     const struct ring_buffer_view* v,
121     uint32_t bytes,
122     uint64_t timeout_us);
123 
124 // read/write fully, blocking if there is nothing to read/write.
125 void ring_buffer_write_fully(
126     struct ring_buffer* r,
127     struct ring_buffer_view* v,
128     const void* data,
129     uint32_t bytes);
130 void ring_buffer_read_fully(
131     struct ring_buffer* r,
132     struct ring_buffer_view* v,
133     void* data,
134     uint32_t bytes);
135 
136 // Like read/write fully, but with an abort value. The value is read from
137 // |abortPtr| each time. If |abortPtr| is null, then behaves the same
138 // as ring_buffer_(read|write)_fully.
139 // Returns the actual number of bytes sent or received.
140 uint32_t ring_buffer_write_fully_with_abort(
141     struct ring_buffer* r,
142     struct ring_buffer_view* v,
143     const void* data,
144     uint32_t bytes,
145     uint32_t abort_value,
146     const volatile uint32_t* abort_ptr);
147 uint32_t ring_buffer_read_fully_with_abort(
148     struct ring_buffer* r,
149     struct ring_buffer_view* v,
150     void* data,
151     uint32_t bytes,
152     uint32_t abort_value,
153     const volatile uint32_t* abort_ptr);
154 
155 uint32_t ring_buffer_view_get_ring_pos(
156     const struct ring_buffer_view* v,
157     uint32_t index);
158 
159 bool ring_buffer_can_write(
160     const struct ring_buffer* r, uint32_t bytes);
161 bool ring_buffer_can_read(
162     const struct ring_buffer* r, uint32_t bytes);
163 bool ring_buffer_view_can_write(
164     const struct ring_buffer* r,
165     const struct ring_buffer_view* v,
166     uint32_t bytes);
167 bool ring_buffer_view_can_read(
168     const struct ring_buffer* r,
169     const struct ring_buffer_view* v,
170     uint32_t bytes);
171 uint32_t ring_buffer_available_read(
172     const struct ring_buffer* r,
173     const struct ring_buffer_view* v);
174 uint32_t ring_buffer_available_write(
175     const struct ring_buffer* r,
176     const struct ring_buffer_view* v);
177 // Copies out contents from the consumer side of
178 // ring buffer/view |r,v|.
179 // If there is less available read than |wanted_bytes|,
180 // returns -1.
181 // On success, returns 0.
182 int ring_buffer_copy_contents(
183     const struct ring_buffer* r,
184     const struct ring_buffer_view* v,
185     uint32_t wanted_bytes,
186     uint8_t* res);
187 
188 // Lockless synchronization where the consumer is allowed to hang up and go to
189 // sleep. This can be considered a sort of asymmetric lock for two threads,
190 // where the consumer can be more sleepy. It captures the pattern we usually use
191 // for emulator devices; the guest asks the host for something, and some host
192 // thread services the request and goes back to sleep.
193 enum ring_buffer_sync_state {
194     RING_BUFFER_SYNC_PRODUCER_IDLE = 0,
195     RING_BUFFER_SYNC_PRODUCER_ACTIVE = 1,
196     RING_BUFFER_SYNC_CONSUMER_HANGING_UP = 2,
197     RING_BUFFER_SYNC_CONSUMER_HUNG_UP = 3,
198 };
199 
200 // Sync state is RING_BUFFER_SYNC_PRODUCER_IDLE.
201 void ring_buffer_sync_init(struct ring_buffer* r);
202 
203 // Tries to acquire the channel for sending.
204 // Returns false if the consumer was in the middle of hanging up,
205 // true if the producer successfully acquired the channel
206 // (put it in the RING_BUFFER_SYNC_PRODUCER_ACTIVE state).
207 bool ring_buffer_producer_acquire(struct ring_buffer* r);
208 // Same as above, but acquires from RING_BUFFER_SYNC_CONSUMER_HUNG_UP.
209 bool ring_buffer_producer_acquire_from_hangup(struct ring_buffer* r);
210 // Waits until the consumer hangs up.
211 void ring_buffer_producer_wait_hangup(struct ring_buffer* r);
212 // Sets the state back to RING_BUFFER_SYNC_PRODUCER_IDLE.
213 void ring_buffer_producer_idle(struct ring_buffer* r);
214 
215 // There is no symmetric consumer acquire because the consumer can consume with
216 // the ring buffer being in any state (albeit with long waiting if the producer
217 // does not send anything)
218 
219 // Tries to acquire the channel on the consumer side for
220 // hanging up. Returns false if the producer is in the middle of sending,
221 // true if the consumer successfully hung up the channel
222 // (put it in the RING_BUFFER_SYNC_CONSUMER_HUNG_UP state).
223 bool ring_buffer_consumer_hangup(struct ring_buffer* r);
224 // Waits until the producer has set the state to
225 // RING_BUFFER_SYNC_PRODUCER_IDLE.
226 void ring_buffer_consumer_wait_producer_idle(struct ring_buffer* r);
227 // Sets the state to hung up.
228 void ring_buffer_consumer_hung_up(struct ring_buffer* r);
229 
230 // Convenient function to reschedule thread
231 void ring_buffer_yield();
232