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