0

I am trying to implement a circular queue that takes a struct

  • ⟶ checks if the queue is full if not enqueues ⟶ else return 0
  • ⟶ checks if the queue is empty if not dequeues ⟶ else return 0

The following is my code :

    #ifndef_QUEUE_H_
    #define QUEUE_H_
    #define QUEUE_SIZE 32

    typedef struct queue 
    {
      int head;
      int tail;
      int buffer[QUEUE_SIZE];
    } queue_t;

    void init_queue(queue_t *);
    int enqueue(queue_t *, int);
    int isfull(queue_t *);
    int dequeue(queue_t *);            
    int queue_empty(queue_t *);            


    #endif
    /* queue.h ends here */


    /* *************************queue.c starts here************************ */
    #include<queue.h>
    #include<stm32f30x.h>

    #define QUEUE_SIZE 32

    int head;
    int tail;

    void init_queue(queue_t *q)
    {
      q->head = 0;
      q->tail = 0;
    }

    int enqueue(queue_t *q, int a )
    {
      if ((((q->head)+1)%QUEUE_SIZE)!=q->tail) 
        {
          q->buffer[q->head]=a;
          q->head=(((q->head)+1)%QUEUE_SIZE);
          return 1 ;
         }
     else 
         {  
            return 0 ;
         }

     }

    int dequeue(queue_t *q)
     {
      int temp ;
      if (queue_empty(q)) 
         {
           return 0;
          }
      else
        {
          temp = q->buffer[q->tail];
          q->tail=((q->tail)+1)%QUEUE_SIZE;
          return temp;
        }

    }

    int queue_empty(queue_t *q)
    {
      if (q->head == q->tail)
        {
          return 1;
        }
      return 0;
    }

    /* **************queue.c ends here********************** */

When I try to test the queue: example enter "hello" and try to print the content inside it it prints "ello hlo elo.." and such incorrect replies.

I am using the enqueue and dequeue function in my getchar and putchar functions. Below are my getchar and putchar functions:

queue_t rxbuf;
queue_t txbuf;
int putchar(int c) 
{

   while(!(enqueue(&txbuf, c)));
}

int nonblockgetchar(void)
{
  dequeue(&rxbuf);
}


int getchar(void) 
{
  int ch;
  while (!(ch=dequeue(&rxbuf)));
  return (ch);
}

Appreciate your time and help.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Nodnin
  • 451
  • 2
  • 9
  • 21
  • Well, what _is_ wrong? What happens when you enqueue an item? What happens when you remove an item? Have you tried stepping through the code in a debugger? – Some programmer dude Feb 16 '13 at 01:43
  • You don't really tell us what problem you see. What did you expect to happen? What actually happens? – sth Feb 16 '13 at 01:44
  • 4
    Be cautious about using `#include ` to pick up your own header. Normally, reserve angle brackets for system headers. Also be cautious about `getchar()` and `putchar()`; there are standard functions with those names, so if you include ``, life will be confusing. – Jonathan Leffler Feb 16 '13 at 01:53
  • 3
    Also, be careful with your header guards. What you've written won't compile (because `#ifdef_QUEUE_H_` is not a valid preprocessor directive). You also need to test and set the same name: `#ifndef QUEUE_H_ / #define QUEUE_H_`. Note that names starting with underscore are 'reserved to the implementation' so you should use a name that does not start with an underscore (you'll know if you're implementing the implementation). – Jonathan Leffler Feb 16 '13 at 01:58
  • 1
    You didn't include your test code. Can you do that? Your putchar and getchar functions use two different queues, so you must be checking the contests of the queue using some other test code. Also, did you remember to initialize your txbuf and rxbuf? And by the way, the usual convention is that you enqueue at the TAIL of the queue and dequeue at the HEAD. You've reversed the two... – Will Nelson Feb 16 '13 at 02:40
  • 1
    Um... `while (!(ch=dequeue(&rxbuf)));` so.. this will just spin into infinity in a single-threaded app so long as the queue is empty (which it always will be, since your only thread is spinning *here*). Is that intentional? Even in a multi-threaded app this is nowhere *near* thread-safe and utterly the wrong way to do this. Have you considered returning EOF as a result from your `getchar()` (which should be renamed to a non-system function name) if the queue is empty and giving your poor CPU a break? Identical issue for `while(!(enqueue(&txbuf, c)));` on the input side, by the way. – WhozCraig Feb 16 '13 at 03:54
  • The code actually is thread safe, as long as there is at most one reader and at most one writer per queue. No locks required. This nifty trick of ring queues is used all the time, for example, in communicating between hardware devices and CPUs via shared memory. If you're not convinced, try to figure out a scenario that breaks down. – Will Nelson Feb 16 '13 at 04:23
  • What is wrong with `boost::circular_buffer`? – phoeagon Feb 17 '13 at 12:49

0 Answers0