fiq_debugger_ringbuf.h revision 2a2f434d743209cda09c68acd63cbcae8e6d17c6
1/* 2 * drivers/staging/android/fiq_debugger/fiq_debugger_ringbuf.h 3 * 4 * simple lockless ringbuffer 5 * 6 * Copyright (C) 2010 Google, Inc. 7 * 8 * This software is licensed under the terms of the GNU General Public 9 * License version 2, as published by the Free Software Foundation, and 10 * may be copied, distributed, and modified under those terms. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 */ 17 18#include <linux/kernel.h> 19#include <linux/slab.h> 20 21struct fiq_debugger_ringbuf { 22 int len; 23 int head; 24 int tail; 25 u8 buf[]; 26}; 27 28 29static inline struct fiq_debugger_ringbuf *fiq_debugger_ringbuf_alloc(int len) 30{ 31 struct fiq_debugger_ringbuf *rbuf; 32 33 rbuf = kzalloc(sizeof(*rbuf) + len, GFP_KERNEL); 34 if (rbuf == NULL) 35 return NULL; 36 37 rbuf->len = len; 38 rbuf->head = 0; 39 rbuf->tail = 0; 40 smp_mb(); 41 42 return rbuf; 43} 44 45static inline void fiq_debugger_ringbuf_free(struct fiq_debugger_ringbuf *rbuf) 46{ 47 kfree(rbuf); 48} 49 50static inline int fiq_debugger_ringbuf_level(struct fiq_debugger_ringbuf *rbuf) 51{ 52 int level = rbuf->head - rbuf->tail; 53 54 if (level < 0) 55 level = rbuf->len + level; 56 57 return level; 58} 59 60static inline int fiq_debugger_ringbuf_room(struct fiq_debugger_ringbuf *rbuf) 61{ 62 return rbuf->len - fiq_debugger_ringbuf_level(rbuf) - 1; 63} 64 65static inline u8 66fiq_debugger_ringbuf_peek(struct fiq_debugger_ringbuf *rbuf, int i) 67{ 68 return rbuf->buf[(rbuf->tail + i) % rbuf->len]; 69} 70 71static inline int 72fiq_debugger_ringbuf_consume(struct fiq_debugger_ringbuf *rbuf, int count) 73{ 74 count = min(count, fiq_debugger_ringbuf_level(rbuf)); 75 76 rbuf->tail = (rbuf->tail + count) % rbuf->len; 77 smp_mb(); 78 79 return count; 80} 81 82static inline int 83fiq_debugger_ringbuf_push(struct fiq_debugger_ringbuf *rbuf, u8 datum) 84{ 85 if (fiq_debugger_ringbuf_room(rbuf) == 0) 86 return 0; 87 88 rbuf->buf[rbuf->head] = datum; 89 smp_mb(); 90 rbuf->head = (rbuf->head + 1) % rbuf->len; 91 smp_mb(); 92 93 return 1; 94} 95