blob: 70747a11e1a40b2923037a7baaf8a72c5d4e7df5 [file] [log] [blame]
Kévin Redon9a12d682018-07-08 13:21:16 +02001/* Ring buffer
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
16 */
Christina Quast4db82e02015-04-11 18:14:41 +020017#include "ringbuffer.h"
18#include "trace.h"
Harald Welte7abdb512016-03-03 17:48:32 +010019#include "utils.h"
Christina Quast542f9182015-04-11 09:31:15 +020020
Kévin Redon9a12d682018-07-08 13:21:16 +020021/* WARNING: Since console output is internally using this ringbuffer to implement
Harald Welte05cc7f62018-07-04 04:39:40 +020022 * buffered writes, we cannot use any TRACE_*() or printf() style functions here,
23 * as it would create infinite recursion! */
24
Harald Welte7dd3dfd2016-03-03 12:32:04 +010025void rbuf_reset(volatile ringbuf * rb)
Christina Quast542f9182015-04-11 09:31:15 +020026{
Harald Welte7abdb512016-03-03 17:48:32 +010027 unsigned long state;
28
29 local_irq_save(state);
Harald Welte7dd3dfd2016-03-03 12:32:04 +010030 rb->ird = 0;
31 rb->iwr = 0;
Harald Welte7abdb512016-03-03 17:48:32 +010032 local_irq_restore(state);
Christina Quast542f9182015-04-11 09:31:15 +020033}
34
Harald Welte7dd3dfd2016-03-03 12:32:04 +010035uint8_t rbuf_read(volatile ringbuf * rb)
Christina Quast542f9182015-04-11 09:31:15 +020036{
Harald Welte7abdb512016-03-03 17:48:32 +010037 unsigned long state;
38 uint8_t val;
39
40 local_irq_save(state);
41 val = rb->buf[rb->ird];
Harald Welte7dd3dfd2016-03-03 12:32:04 +010042 rb->ird = (rb->ird + 1) % RING_BUFLEN;
Harald Welte7abdb512016-03-03 17:48:32 +010043 local_irq_restore(state);
44
Harald Welte7dd3dfd2016-03-03 12:32:04 +010045 return val;
Christina Quast542f9182015-04-11 09:31:15 +020046}
47
Harald Welte7dd3dfd2016-03-03 12:32:04 +010048uint8_t rbuf_peek(volatile ringbuf * rb)
Christina Quast7a7f98c2015-05-02 14:10:13 +020049{
Harald Welte7dd3dfd2016-03-03 12:32:04 +010050 return rb->buf[rb->ird];
Christina Quast7a7f98c2015-05-02 14:10:13 +020051}
52
Harald Welte7dd3dfd2016-03-03 12:32:04 +010053bool rbuf_is_empty(volatile ringbuf * rb)
Christina Quast4db82e02015-04-11 18:14:41 +020054{
Harald Welte7dd3dfd2016-03-03 12:32:04 +010055 return rb->ird == rb->iwr;
Christina Quast4db82e02015-04-11 18:14:41 +020056}
57
Harald Welte7abdb512016-03-03 17:48:32 +010058static bool __rbuf_is_full(volatile ringbuf * rb)
Christina Quast4db82e02015-04-11 18:14:41 +020059{
Harald Welte7dd3dfd2016-03-03 12:32:04 +010060 return rb->ird == (rb->iwr + 1) % RING_BUFLEN;
Christina Quast4db82e02015-04-11 18:14:41 +020061}
Harald Welte7abdb512016-03-03 17:48:32 +010062
63bool rbuf_is_full(volatile ringbuf * rb)
64{
65 unsigned long state;
66 bool rc;
67
68 local_irq_save(state);
69 rc = rb->ird == (rb->iwr + 1) % RING_BUFLEN;
70 local_irq_restore(state);
71
72 return rc;
73}
74
Harald Welte05cc7f62018-07-04 04:39:40 +020075int rbuf_write(volatile ringbuf * rb, uint8_t item)
Harald Welte7abdb512016-03-03 17:48:32 +010076{
77 unsigned long state;
78
79 local_irq_save(state);
80 if (!__rbuf_is_full(rb)) {
81 rb->buf[rb->iwr] = item;
82 rb->iwr = (rb->iwr + 1) % RING_BUFLEN;
83 local_irq_restore(state);
Harald Welte05cc7f62018-07-04 04:39:40 +020084 return 0;
Harald Welte7abdb512016-03-03 17:48:32 +010085 } else {
86 local_irq_restore(state);
Harald Welte05cc7f62018-07-04 04:39:40 +020087 return -1;
Harald Welte7abdb512016-03-03 17:48:32 +010088 }
89}
90
91