qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

fifo8.c (2670B)


      1 /*
      2  * Generic FIFO component, implemented as a circular buffer.
      3  *
      4  * Copyright (c) 2012 Peter A. G. Crosthwaite
      5  *
      6  * This program is free software; you can redistribute it and/or
      7  * modify it under the terms of the GNU General Public License
      8  * as published by the Free Software Foundation; either version
      9  * 2 of the License, or (at your option) any later version.
     10  *
     11  * You should have received a copy of the GNU General Public License along
     12  * with this program; if not, see <http://www.gnu.org/licenses/>.
     13  */
     14 
     15 #include "qemu/osdep.h"
     16 #include "migration/vmstate.h"
     17 #include "qemu/fifo8.h"
     18 
     19 void fifo8_create(Fifo8 *fifo, uint32_t capacity)
     20 {
     21     fifo->data = g_new(uint8_t, capacity);
     22     fifo->capacity = capacity;
     23     fifo->head = 0;
     24     fifo->num = 0;
     25 }
     26 
     27 void fifo8_destroy(Fifo8 *fifo)
     28 {
     29     g_free(fifo->data);
     30 }
     31 
     32 void fifo8_push(Fifo8 *fifo, uint8_t data)
     33 {
     34     assert(fifo->num < fifo->capacity);
     35     fifo->data[(fifo->head + fifo->num) % fifo->capacity] = data;
     36     fifo->num++;
     37 }
     38 
     39 void fifo8_push_all(Fifo8 *fifo, const uint8_t *data, uint32_t num)
     40 {
     41     uint32_t start, avail;
     42 
     43     assert(fifo->num + num <= fifo->capacity);
     44 
     45     start = (fifo->head + fifo->num) % fifo->capacity;
     46 
     47     if (start + num <= fifo->capacity) {
     48         memcpy(&fifo->data[start], data, num);
     49     } else {
     50         avail = fifo->capacity - start;
     51         memcpy(&fifo->data[start], data, avail);
     52         memcpy(&fifo->data[0], &data[avail], num - avail);
     53     }
     54 
     55     fifo->num += num;
     56 }
     57 
     58 uint8_t fifo8_pop(Fifo8 *fifo)
     59 {
     60     uint8_t ret;
     61 
     62     assert(fifo->num > 0);
     63     ret = fifo->data[fifo->head++];
     64     fifo->head %= fifo->capacity;
     65     fifo->num--;
     66     return ret;
     67 }
     68 
     69 const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *num)
     70 {
     71     uint8_t *ret;
     72 
     73     assert(max > 0 && max <= fifo->num);
     74     *num = MIN(fifo->capacity - fifo->head, max);
     75     ret = &fifo->data[fifo->head];
     76     fifo->head += *num;
     77     fifo->head %= fifo->capacity;
     78     fifo->num -= *num;
     79     return ret;
     80 }
     81 
     82 void fifo8_reset(Fifo8 *fifo)
     83 {
     84     fifo->num = 0;
     85     fifo->head = 0;
     86 }
     87 
     88 bool fifo8_is_empty(Fifo8 *fifo)
     89 {
     90     return (fifo->num == 0);
     91 }
     92 
     93 bool fifo8_is_full(Fifo8 *fifo)
     94 {
     95     return (fifo->num == fifo->capacity);
     96 }
     97 
     98 uint32_t fifo8_num_free(Fifo8 *fifo)
     99 {
    100     return fifo->capacity - fifo->num;
    101 }
    102 
    103 uint32_t fifo8_num_used(Fifo8 *fifo)
    104 {
    105     return fifo->num;
    106 }
    107 
    108 const VMStateDescription vmstate_fifo8 = {
    109     .name = "Fifo8",
    110     .version_id = 1,
    111     .minimum_version_id = 1,
    112     .fields = (VMStateField[]) {
    113         VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, capacity),
    114         VMSTATE_UINT32(head, Fifo8),
    115         VMSTATE_UINT32(num, Fifo8),
    116         VMSTATE_END_OF_LIST()
    117     }
    118 };