diff options
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/kfifo.h | 80 |
1 files changed, 35 insertions, 45 deletions
diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index c3f8d82efd34..e0f5c9d4197d 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h | |||
| @@ -30,13 +30,12 @@ struct kfifo { | |||
| 30 | unsigned int size; /* the size of the allocated buffer */ | 30 | unsigned int size; /* the size of the allocated buffer */ |
| 31 | unsigned int in; /* data is added at offset (in % size) */ | 31 | unsigned int in; /* data is added at offset (in % size) */ |
| 32 | unsigned int out; /* data is extracted from off. (out % size) */ | 32 | unsigned int out; /* data is extracted from off. (out % size) */ |
| 33 | spinlock_t *lock; /* protects concurrent modifications */ | ||
| 34 | }; | 33 | }; |
| 35 | 34 | ||
| 36 | extern void kfifo_init(struct kfifo *fifo, unsigned char *buffer, | 35 | extern void kfifo_init(struct kfifo *fifo, unsigned char *buffer, |
| 37 | unsigned int size, spinlock_t *lock); | 36 | unsigned int size); |
| 38 | extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size, | 37 | extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size, |
| 39 | gfp_t gfp_mask, spinlock_t *lock); | 38 | gfp_t gfp_mask); |
| 40 | extern void kfifo_free(struct kfifo *fifo); | 39 | extern void kfifo_free(struct kfifo *fifo); |
| 41 | extern unsigned int __kfifo_put(struct kfifo *fifo, | 40 | extern unsigned int __kfifo_put(struct kfifo *fifo, |
| 42 | const unsigned char *buffer, unsigned int len); | 41 | const unsigned char *buffer, unsigned int len); |
| @@ -58,58 +57,67 @@ static inline void __kfifo_reset(struct kfifo *fifo) | |||
| 58 | */ | 57 | */ |
| 59 | static inline void kfifo_reset(struct kfifo *fifo) | 58 | static inline void kfifo_reset(struct kfifo *fifo) |
| 60 | { | 59 | { |
| 61 | unsigned long flags; | ||
| 62 | |||
| 63 | spin_lock_irqsave(fifo->lock, flags); | ||
| 64 | |||
| 65 | __kfifo_reset(fifo); | 60 | __kfifo_reset(fifo); |
| 61 | } | ||
| 62 | |||
| 63 | /** | ||
| 64 | * __kfifo_len - returns the number of bytes available in the FIFO | ||
| 65 | * @fifo: the fifo to be used. | ||
| 66 | */ | ||
| 67 | static inline unsigned int __kfifo_len(struct kfifo *fifo) | ||
| 68 | { | ||
| 69 | register unsigned int out; | ||
| 66 | 70 | ||
| 67 | spin_unlock_irqrestore(fifo->lock, flags); | 71 | out = fifo->out; |
| 72 | smp_rmb(); | ||
| 73 | return fifo->in - out; | ||
| 68 | } | 74 | } |
| 69 | 75 | ||
| 70 | /** | 76 | /** |
| 71 | * kfifo_put - puts some data into the FIFO | 77 | * kfifo_put_locked - puts some data into the FIFO using a spinlock for locking |
| 72 | * @fifo: the fifo to be used. | 78 | * @fifo: the fifo to be used. |
| 73 | * @buffer: the data to be added. | 79 | * @from: the data to be added. |
| 74 | * @len: the length of the data to be added. | 80 | * @n: the length of the data to be added. |
| 81 | * @lock: pointer to the spinlock to use for locking. | ||
| 75 | * | 82 | * |
| 76 | * This function copies at most @len bytes from the @buffer into | 83 | * This function copies at most @len bytes from the @from buffer into |
| 77 | * the FIFO depending on the free space, and returns the number of | 84 | * the FIFO depending on the free space, and returns the number of |
| 78 | * bytes copied. | 85 | * bytes copied. |
| 79 | */ | 86 | */ |
| 80 | static inline unsigned int kfifo_put(struct kfifo *fifo, | 87 | static inline __must_check unsigned int kfifo_put_locked(struct kfifo *fifo, |
| 81 | const unsigned char *buffer, unsigned int len) | 88 | const unsigned char *from, unsigned int n, spinlock_t *lock) |
| 82 | { | 89 | { |
| 83 | unsigned long flags; | 90 | unsigned long flags; |
| 84 | unsigned int ret; | 91 | unsigned int ret; |
| 85 | 92 | ||
| 86 | spin_lock_irqsave(fifo->lock, flags); | 93 | spin_lock_irqsave(lock, flags); |
| 87 | 94 | ||
| 88 | ret = __kfifo_put(fifo, buffer, len); | 95 | ret = __kfifo_put(fifo, from, n); |
| 89 | 96 | ||
| 90 | spin_unlock_irqrestore(fifo->lock, flags); | 97 | spin_unlock_irqrestore(lock, flags); |
| 91 | 98 | ||
| 92 | return ret; | 99 | return ret; |
| 93 | } | 100 | } |
| 94 | 101 | ||
| 95 | /** | 102 | /** |
| 96 | * kfifo_get - gets some data from the FIFO | 103 | * kfifo_get_locked - gets some data from the FIFO using a spinlock for locking |
| 97 | * @fifo: the fifo to be used. | 104 | * @fifo: the fifo to be used. |
| 98 | * @buffer: where the data must be copied. | 105 | * @to: where the data must be copied. |
| 99 | * @len: the size of the destination buffer. | 106 | * @n: the size of the destination buffer. |
| 107 | * @lock: pointer to the spinlock to use for locking. | ||
| 100 | * | 108 | * |
| 101 | * This function copies at most @len bytes from the FIFO into the | 109 | * This function copies at most @len bytes from the FIFO into the |
| 102 | * @buffer and returns the number of copied bytes. | 110 | * @to buffer and returns the number of copied bytes. |
| 103 | */ | 111 | */ |
| 104 | static inline unsigned int kfifo_get(struct kfifo *fifo, | 112 | static inline __must_check unsigned int kfifo_get_locked(struct kfifo *fifo, |
| 105 | unsigned char *buffer, unsigned int len) | 113 | unsigned char *to, unsigned int n, spinlock_t *lock) |
| 106 | { | 114 | { |
| 107 | unsigned long flags; | 115 | unsigned long flags; |
| 108 | unsigned int ret; | 116 | unsigned int ret; |
| 109 | 117 | ||
| 110 | spin_lock_irqsave(fifo->lock, flags); | 118 | spin_lock_irqsave(lock, flags); |
| 111 | 119 | ||
| 112 | ret = __kfifo_get(fifo, buffer, len); | 120 | ret = __kfifo_get(fifo, to, n); |
| 113 | 121 | ||
| 114 | /* | 122 | /* |
| 115 | * optimization: if the FIFO is empty, set the indices to 0 | 123 | * optimization: if the FIFO is empty, set the indices to 0 |
| @@ -118,36 +126,18 @@ static inline unsigned int kfifo_get(struct kfifo *fifo, | |||
| 118 | if (fifo->in == fifo->out) | 126 | if (fifo->in == fifo->out) |
| 119 | fifo->in = fifo->out = 0; | 127 | fifo->in = fifo->out = 0; |
| 120 | 128 | ||
| 121 | spin_unlock_irqrestore(fifo->lock, flags); | 129 | spin_unlock_irqrestore(lock, flags); |
| 122 | 130 | ||
| 123 | return ret; | 131 | return ret; |
| 124 | } | 132 | } |
| 125 | 133 | ||
| 126 | /** | 134 | /** |
| 127 | * __kfifo_len - returns the number of bytes available in the FIFO, no locking version | ||
| 128 | * @fifo: the fifo to be used. | ||
| 129 | */ | ||
| 130 | static inline unsigned int __kfifo_len(struct kfifo *fifo) | ||
| 131 | { | ||
| 132 | return fifo->in - fifo->out; | ||
| 133 | } | ||
| 134 | |||
| 135 | /** | ||
| 136 | * kfifo_len - returns the number of bytes available in the FIFO | 135 | * kfifo_len - returns the number of bytes available in the FIFO |
| 137 | * @fifo: the fifo to be used. | 136 | * @fifo: the fifo to be used. |
| 138 | */ | 137 | */ |
| 139 | static inline unsigned int kfifo_len(struct kfifo *fifo) | 138 | static inline unsigned int kfifo_len(struct kfifo *fifo) |
| 140 | { | 139 | { |
| 141 | unsigned long flags; | 140 | return __kfifo_len(fifo); |
| 142 | unsigned int ret; | ||
| 143 | |||
| 144 | spin_lock_irqsave(fifo->lock, flags); | ||
| 145 | |||
| 146 | ret = __kfifo_len(fifo); | ||
| 147 | |||
| 148 | spin_unlock_irqrestore(fifo->lock, flags); | ||
| 149 | |||
| 150 | return ret; | ||
| 151 | } | 141 | } |
| 152 | 142 | ||
| 153 | #endif | 143 | #endif |
