zheng_ji_yi

    1. 我对如何编写高质量的程序的看法 7/3524 嵌入式系统 2008-08-04
      /** * __kfifo_get - gets some data from the FIFO, no locking version * @fifo: the fifo to be used. * @buffer: where the data must be copied. * @len: the size of the destination buffer. * * This function copies at most 'len' bytes from the FIFO into the * 'buffer' and returns the number of copied bytes. * * Note that with only one concurrent reader and one concurrent * writer, you don't need extra locking to use these functions. */ unsigned int __kfifo_get(struct kfifo *fifo,              unsigned char *buffer, unsigned int len) {     unsigned int l;     len = min(len, fifo->in - fifo->out);     /* first get the data from fifo->out until the end of the buffer */     l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));     memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l);     /* then get the rest (if any) from the beginning of the buffer */     memcpy(buffer + l, fifo->buffer, len - l);     fifo->out += len;     return len; } EXPORT_SYMBOL(__kfifo_get); 头文件kfifo.h /* * A simple kernel FIFO implementation. * * Copyright (C) 2004 Stelian Pop * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef _LINUX_KFIFO_H #define _LINUX_KFIFO_H #ifdef __KERNEL__ #include #include struct kfifo {     unsigned char *buffer;    /* the buffer holding the data */     unsigned int size;    /* the size of the allocated buffer */     unsigned int in;    /* data is added at offset (in % size) */     unsigned int out;    /* data is extracted from off. (out % size) */     spinlock_t *lock;    /* protects concurrent modifications */ }; extern struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size,                 gfp_t gfp_mask, spinlock_t *lock); extern struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask,                  spinlock_t *lock); extern void kfifo_free(struct kfifo *fifo); extern unsigned int __kfifo_put(struct kfifo *fifo,                 unsigned char *buffer, unsigned int len); extern unsigned int __kfifo_get(struct kfifo *fifo,                 unsigned char *buffer, unsigned int len); /** * __kfifo_reset - removes the entire FIFO contents, no locking version * @fifo: the fifo to be emptied. */ static inline void __kfifo_reset(struct kfifo *fifo) {     fifo->in = fifo->out = 0; } /** * kfifo_reset - removes the entire FIFO contents * @fifo: the fifo to be emptied. */ static inline void kfifo_reset(struct kfifo *fifo) {     unsigned long flags;     spin_lock_irqsave(fifo->lock, flags);     __kfifo_reset(fifo);     spin_unlock_irqrestore(fifo->lock, flags); } /** * kfifo_put - puts some data into the FIFO * @fifo: the fifo to be used. * @buffer: the data to be added. * @len: the length of the data to be added. * * This function copies at most 'len' bytes from the 'buffer' into * the FIFO depending on the free space, and returns the number of * bytes copied. */ static inline unsigned int kfifo_put(struct kfifo *fifo,                      unsigned char *buffer, unsigned int len) {     unsigned long flags;     unsigned int ret;     spin_lock_irqsave(fifo->lock, flags);     ret = __kfifo_put(fifo, buffer, len);     spin_unlock_irqrestore(fifo->lock, flags);     return ret; } /** * kfifo_get - gets some data from the FIFO * @fifo: the fifo to be used. * @buffer: where the data must be copied. * @len: the size of the destination buffer. * * This function copies at most 'len' bytes from the FIFO into the * 'buffer' and returns the number of copied bytes. */ static inline unsigned int kfifo_get(struct kfifo *fifo,                      unsigned char *buffer, unsigned int len) {     unsigned long flags;     unsigned int ret;     spin_lock_irqsave(fifo->lock, flags);     ret = __kfifo_get(fifo, buffer, len);     /*      * optimization: if the FIFO is empty, set the indices to 0      * so we don't wrap the next time      */     if (fifo->in == fifo->out)         fifo->in = fifo->out = 0;     spin_unlock_irqrestore(fifo->lock, flags);     return ret; } /** * __kfifo_len - returns the number of bytes available in the FIFO, no locking version * @fifo: the fifo to be used. */ static inline unsigned int __kfifo_len(struct kfifo *fifo) {     return fifo->in - fifo->out; } /** * kfifo_len - returns the number of bytes available in the FIFO * @fifo: the fifo to be used. */ static inline unsigned int kfifo_len(struct kfifo *fifo) {     unsigned long flags;     unsigned int ret;     spin_lock_irqsave(fifo->lock, flags);     ret = __kfifo_len(fifo);     spin_unlock_irqrestore(fifo->lock, flags);     return ret; } #else #warning "don't include kernel headers in userspace" #endif /* __KERNEL__ */ #endif
    2. 我对如何编写高质量的程序的看法 7/3524 嵌入式系统 2008-08-04
      EXPORT_SYMBOL(kfifo_init); /** * kfifo_alloc - allocates a new FIFO and its internal buffer * @size: the size of the internal buffer to be allocated. * @gfp_mask: get_free_pages mask, passed to kmalloc() * @lock: the lock to be used to protect the fifo buffer * * The size will be rounded-up to a power of 2. */ struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock) {     unsigned char *buffer;     struct kfifo *ret;     /*      * round up to the next power of 2, since our 'let the indices      * wrap' tachnique works only in this case.      */     if (size & (size - 1)) {         BUG_ON(size > 0x80000000);         size = roundup_pow_of_two(size);     }     buffer = kmalloc(size, gfp_mask);     if (!buffer)         return ERR_PTR(-ENOMEM);     ret = kfifo_init(buffer, size, gfp_mask, lock);     if (IS_ERR(ret))         kfree(buffer);     return ret; } EXPORT_SYMBOL(kfifo_alloc); /** * kfifo_free - frees the FIFO * @fifo: the fifo to be freed. */ void kfifo_free(struct kfifo *fifo) {     kfree(fifo->buffer);     kfree(fifo); } EXPORT_SYMBOL(kfifo_free); /** * __kfifo_put - puts some data into the FIFO, no locking version * @fifo: the fifo to be used. * @buffer: the data to be added. * @len: the length of the data to be added. * * This function copies at most 'len' bytes from the 'buffer' into * the FIFO depending on the free space, and returns the number of * bytes copied. * * Note that with only one concurrent reader and one concurrent * writer, you don't need extra locking to use these functions. */ unsigned int __kfifo_put(struct kfifo *fifo,              unsigned char *buffer, unsigned int len) {     unsigned int l;     len = min(len, fifo->size - fifo->in + fifo->out);     /* first put the data starting from fifo->in to buffer end */     l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));     memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l);     /* then put the rest (if any) at the beginning of the buffer */     memcpy(fifo->buffer, buffer + l, len - l);     fifo->in += len;     return len; } EXPORT_SYMBOL(__kfifo_put);
    3. 我对如何编写高质量的程序的看法 7/3524 嵌入式系统 2008-08-04
      大体看了看代码,改进的地方很大,需要更加努力!建议多看看人家的代码。附上linux内核实现的fifo。 kfifo.c /* * A simple kernel FIFO implementation. * * Copyright (C) 2004 Stelian Pop * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include #include /** * kfifo_init - allocates a new FIFO using a preallocated buffer * @buffer: the preallocated buffer to be used. * @size: the size of the internal buffer, this have to be a power of 2. * @gfp_mask: get_free_pages mask, passed to kmalloc() * @lock: the lock to be used to protect the fifo buffer * * Do NOT pass the kfifo to kfifo_free() after use ! Simply free the * struct kfifo with kfree(). */ struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size,              gfp_t gfp_mask, spinlock_t *lock) {     struct kfifo *fifo;     /* size must be a power of 2 */     BUG_ON(size & (size - 1));     fifo = kmalloc(sizeof(struct kfifo), gfp_mask);     if (!fifo)         return ERR_PTR(-ENOMEM);     fifo->buffer = buffer;     fifo->size = size;     fifo->in = fifo->out = 0;     fifo->lock = lock;     return fifo; }

最近访客

< 1/1 >

统计信息

已有46人来访过

  • 芯积分:--
  • 好友:--
  • 主题:--
  • 回复:3

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言