diff options
author | Yuval Peress <peress@chromium.org> | 2019-05-30 13:48:49 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-06-05 18:50:21 +0000 |
commit | b4f1c3ca375f6e3c50edae12c1713236a0bcd2cc (patch) | |
tree | 1723be9eda2e3ae36907c6d176c2e5768a53b550 /common | |
parent | 01fd86385bdcf633db0acd91b5f60733097a84a3 (diff) | |
download | chrome-ec-b4f1c3ca375f6e3c50edae12c1713236a0bcd2cc.tar.gz |
common: queue: Update chunk struct and get read/write logic
This change updates the queue_get_write_chunk and
queue_get_read_chunk logic to return an updated queue_chunk.
The new chunk uses a void * for the buffer and replaces length
with count. This more tightly aligns to how the rest of the
queue functions operate. Further, it adds the ability to
offset the write chunk. This is important as it allows wrapping.
For example:
With a queue of 8 units, 1 byte each. Assume H=2, T=5. Previously,
we were only able to ever get the 3 bytes at 5-7. Using the offset
of 3 though, we can now also get the 2 byte write chunk 0-1.
BUG=chromium:966506
BRANCH=None
TEST=Added unit tests
Change-Id: I40216c36aa0dc95ec4d15fc587d4b1f08a17ef73
Signed-off-by: Yuval Peress <peress@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1637415
Reviewed-by: Enrico Granata <egranata@chromium.org>
Reviewed-by: Jett Rink <jettrink@chromium.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/queue.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/common/queue.c b/common/queue.c index 780bd41d3b..c8436344c1 100644 --- a/common/queue.c +++ b/common/queue.c @@ -67,17 +67,23 @@ int queue_is_full(struct queue const *q) * |****************| */ -struct queue_chunk queue_get_write_chunk(struct queue const *q) +struct queue_chunk queue_get_write_chunk(struct queue const *q, size_t offset) { size_t head = q->state->head & q->buffer_units_mask; - size_t tail = q->state->tail & q->buffer_units_mask; - size_t last = (queue_is_full(q) ? tail : /* Full */ - ((tail < head) ? head : /* Wrapped */ - q->buffer_units)); /* Normal | Empty */ + size_t tail = (q->state->tail + offset) & q->buffer_units_mask; + size_t last = (tail < head) ? head : /* Wrapped */ + q->buffer_units; /* Normal | Empty */ + + /* Make sure that the offset doesn't exceed free space. */ + if (queue_space(q) <= offset) + return ((struct queue_chunk) { + .count = 0, + .buffer = NULL, + }); return ((struct queue_chunk) { - .length = (last - tail) * q->unit_bytes, - .buffer = q->buffer + tail * q->unit_bytes, + .count = last - tail, + .buffer = q->buffer + (tail * q->unit_bytes), }); } @@ -90,8 +96,8 @@ struct queue_chunk queue_get_read_chunk(struct queue const *q) q->buffer_units)); /* Wrapped | Full */ return ((struct queue_chunk) { - .length = (last - head) * q->unit_bytes, - .buffer = q->buffer + head * q->unit_bytes, + .count = (last - head), + .buffer = q->buffer + (head * q->unit_bytes), }); } |