1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <assert.h>
6 #include <string.h>
7
8 #include "pty-fifo.h"
9
10 static_assert((PTY_FIFO_SIZE & (PTY_FIFO_SIZE - 1)) == 0, "fifo size not power of two");
11
12 #define PTY_FIFO_MASK (PTY_FIFO_SIZE - 1)
13
pty_fifo_write(pty_fifo_t * fifo,const void * data,size_t len,bool atomic)14 size_t pty_fifo_write(pty_fifo_t* fifo, const void* data, size_t len, bool atomic) {
15 size_t avail = PTY_FIFO_SIZE - (fifo->head - fifo->tail);
16 if (avail < len) {
17 if (atomic) {
18 return 0;
19 }
20 len = avail;
21 }
22
23 size_t offset = fifo->head & PTY_FIFO_MASK;
24
25 avail = PTY_FIFO_SIZE - offset;
26 if (len <= avail) {
27 memcpy(fifo->data + offset, data, len);
28 } else {
29 memcpy(fifo->data + offset, data, avail);
30 memcpy(fifo->data, data + avail, len - avail);
31 }
32
33 fifo->head += len;
34 return len;
35 }
36
pty_fifo_read(pty_fifo_t * fifo,void * data,size_t len)37 size_t pty_fifo_read(pty_fifo_t* fifo, void* data, size_t len) {
38 size_t avail = fifo->head - fifo->tail;
39 if (avail < len) {
40 len = avail;
41 }
42
43 size_t offset = fifo->tail & PTY_FIFO_MASK;
44
45 avail = PTY_FIFO_SIZE - offset;
46 if (len <= avail) {
47 memcpy(data, fifo->data + offset, len);
48 } else {
49 memcpy(data, fifo->data + offset, avail);
50 memcpy(data + avail, fifo->data, len - avail);
51 }
52
53 fifo->tail += len;
54 return len;
55 }
56
57