/* * internal helper to calculate the unused elements in a fifo
*/ staticinlineunsignedint kfifo_unused(struct __kfifo *fifo)
{ return (fifo->mask + 1) - (fifo->in - fifo->out);
}
int __kfifo_alloc(struct __kfifo *fifo, unsignedint size,
size_t esize, gfp_t gfp_mask)
{ /* * round up to the next power of 2, since our 'let the indices * wrap' technique works only in this case.
*/
size = roundup_pow_of_two(size);
off &= fifo->mask; if (esize != 1) {
off *= esize;
size *= esize;
len *= esize;
}
l = min(len, size - off);
memcpy(fifo->data + off, src, l);
memcpy(fifo->data, src + l, len - l); /* * make sure that the data in the fifo is up to date before * incrementing the fifo->in index counter
*/
smp_wmb();
}
off &= fifo->mask; if (esize != 1) {
off *= esize;
size *= esize;
len *= esize;
}
l = min(len, size - off);
memcpy(dst, fifo->data + off, l);
memcpy(dst + l, fifo->data, len - l); /* * make sure that the data is copied before * incrementing the fifo->out index counter
*/
smp_wmb();
}
off &= fifo->mask; if (esize != 1) {
off *= esize;
size *= esize;
len *= esize;
}
l = min(len, size - off);
ret = copy_from_user(fifo->data + off, from, l); if (unlikely(ret))
ret = DIV_ROUND_UP(ret + len - l, esize); else {
ret = copy_from_user(fifo->data, from + l, len - l); if (unlikely(ret))
ret = DIV_ROUND_UP(ret, esize);
} /* * make sure that the data in the fifo is up to date before * incrementing the fifo->in index counter
*/
smp_wmb();
*copied = len - ret * esize; /* return the number of elements which are not copied */ return ret;
}
off &= fifo->mask; if (esize != 1) {
off *= esize;
size *= esize;
len *= esize;
}
l = min(len, size - off);
ret = copy_to_user(to, fifo->data + off, l); if (unlikely(ret))
ret = DIV_ROUND_UP(ret + len - l, esize); else {
ret = copy_to_user(to + l, fifo->data, len - l); if (unlikely(ret))
ret = DIV_ROUND_UP(ret, esize);
} /* * make sure that the data is copied before * incrementing the fifo->out index counter
*/
smp_wmb();
*copied = len - ret * esize; /* return the number of elements which are not copied */ return ret;
}
if (len > max) return max; return len;
}
EXPORT_SYMBOL(__kfifo_max_r);
#define __KFIFO_PEEK(data, out, mask) \
((data)[(out) & (mask)]) /* * __kfifo_peek_n internal helper function for determinate the length of * the next record in the fifo
*/ staticunsignedint __kfifo_peek_n(struct __kfifo *fifo, size_t recsize)
{ unsignedint l; unsignedint mask = fifo->mask; unsignedchar *data = fifo->data;
l = __KFIFO_PEEK(data, fifo->out, mask);
if (--recsize)
l |= __KFIFO_PEEK(data, fifo->out + 1, mask) << 8;
/* * __kfifo_poke_n internal helper function for storing the length of * the record into the fifo
*/ staticvoid __kfifo_poke_n(struct __kfifo *fifo, unsignedint n, size_t recsize)
{ unsignedint mask = fifo->mask; unsignedchar *data = fifo->data;
__KFIFO_POKE(data, fifo->in, mask, n);
if (recsize > 1)
__KFIFO_POKE(data, fifo->in + 1, mask, n >> 8);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.