Thread: Access a FIFO(Circular Queue) between two cores

  1. #1
    Registered User
    Join Date
    Oct 2014
    Posts
    7

    Question Access a FIFO(Circular Queue) between two cores

    Hi,
    I want to write a program where one core (core 0) will fill the FIFO and other core (core 1 ) will delete the data from FIFO.

    Core 0:

    I create a fifo
    Code:
    struct node
    {
        int info;
        struct node *ptr;
    }*front,*rear,*temp,*front1;
    and my en-queue function is in core 0 and writing to specific memory location..(which works perfectly)
    Code:
    void enq(int data)
    {
            if (rear == NULL)
            {
                    rear = (struct node *)malloc(1*sizeof(struct node));
                    rear->ptr = NULL;
                    rear->info = data;
                    front = rear;
                    
            }
            else
            {
                    temp=(struct node *)malloc(1*sizeof(struct node));
                    rear->ptr = temp;
                    temp->info = data;
                    temp->ptr = NULL;
                    rear = temp;
           
            }
    }
    Now the problem is in the core 1. Here I am unable to read the values from the specific memory location. I am getting garbage value. Where I am doing some stupid error.. I did not understand

    Code:
            (front->ptr) = (unsigned int *) memory_location;
    WHen I print the (front->ptr) it shows correct memory address but inside the
    the De-queue function in core 1, I am getting wrong value..
    Code:
    int deq(int buf[n])
    {
            front1 = front;
            printf("Val %d ", front->info); // showing wrong value
            if (front1 == NULL)
            {
                printf("\n Error: Trying to display elements from empty queue");
                return 0;
            }
            else
                    if (front1->ptr != NULL)
                    {
                            front1 = front1->ptr;
                            printf("\n Dequed value : %d", front->info);
                            free(front);
                            front = front1;
                            buf[n] = front->info;
                    }
                    else
                    {
                            printf("\n Dequed value : %d", front->info);
                            buf[n] = front->info;
    
    
                            free(front);
                            front = NULL;
                            rear = NULL;
                    }
    return 0;
    }

    I already lost more than one day to solve it.. Please help...

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,125
    Let's just be clear here - when you say "core0" and "core1", you're talking about separate processes running on a machine which implements virtual memory.

    > (front->ptr) = (unsigned int *) memory_location;
    So no, you can't just copy an address from one process, paste it into another process and expect to be able to read data.

    Begin by telling us which OS you're using, then we can discuss suitable shared memory ideas.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Apr 2013
    Posts
    1,656
    I'm assuming you mean two threads running on two cores. One issue with deq() is that it's called with a buffer of size n, then stores data a buf[n], which is one past the end of the buffer. Also the code is using a conventional linked list, as opposed to an array or vector used as a circular fifo. A linked list can also be circular, with the last node pointing towards the first node, but I'm not sure that counts as a circular fifo. You could use a mutex to protect pointer or indexes that are occasionally access by both threads, such as transitions between an empty and non-empty fifo. The alternative is to include a count, and protect that with a mutex, or two semaphores (assuming the OS implements these with atomic operations), eliminating the need to protect pointer or index access between the two threads.

  4. #4
    Registered User
    Join Date
    Oct 2014
    Posts
    7
    Quote Originally Posted by Salem View Post
    Let's just be clear here - when you say "core0" and "core1", you're talking about separate processes running on a machine which implements virtual memory.

    > (front->ptr) = (unsigned int *) memory_location;
    So no, you can't just copy an address from one process, paste it into another process and expect to be able to read data.

    Begin by telling us which OS you're using, then we can discuss suitable shared memory ideas.
    Thanks for the reply. I am using Linux and rcgldr is correct. I am using two threads running on two cores. The memory area (memory location) is shared between two processes (no virtual memory)..

  5. #5
    Registered User
    Join Date
    Oct 2014
    Posts
    7
    Quote Originally Posted by rcgldr View Post
    I'm assuming you mean two threads running on two cores.
    Yes.. you got it right...
    One issue with deq() is that it's called with a buffer of size n, then stores data a buf[n], which is one past the end of the buffer.
    Here the buffer is used used to hold the deleted values for further calculations.
    Also the code is using a conventional linked list, as opposed to an array or vector used as a circular fifo. A linked list can also be circular, with the last node pointing towards the first node, but I'm not sure that counts as a circular fifo.
    I thought it would be easier to handle the situation. Do you think the array approach would be easier to solve this issue.
    You could use a mutex to protect pointer or indexes that are occasionally access by both threads, such as transitions between an empty and non-empty fifo. The alternative is to include a count, and protect that with a mutex, or two semaphores (assuming the OS implements these with atomic operations), eliminating the need to protect pointer or index access between the two threads.

    I will use mutex but it was just the basic code. If it works fine then then I can make it complex by adding these features.. Here I did not need mutex as it is just write to the fifo and the next thread will pop these values.. That's it.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,125
    You need a mutex.

    Any variable which can be written by one thread and read by another needs to be guarded.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Apr 2013
    Posts
    1,656
    Quote Originally Posted by santy View Post
    Do you think the array approach would be easier to solve this issue?
    Since the title of this thread is "circular fifo", that implies an array or vector of nodes used as a circular buffer, or a circular linked list of fixed size. The example code uses a linked list, but its a conventional linked list and not a circular one.

    Yet another option is to create a linked list of fixed size to be used as a free pool of nodes that are retrieved one at a time by the first thread to be filled in, then appended to the input queue (list) of the "other" thread". Then once the other thread was done with a node, it would return that node to the "free pool". In this case I use both a mutex (to protect list operations), and a semaphore (to wait for a non-empty list) for each list (in this case two sets, the "free pool", and the other thread's "input queue). Windows has a wait for multiple objects function that allows a thread to wait for both a mutex and a non-zero semaphore in a single atomic call. I don't know about other systems.
    Last edited by rcgldr; 11-01-2014 at 01:48 PM.

  8. #8
    Registered User
    Join Date
    Oct 2014
    Posts
    7
    Quote Originally Posted by rcgldr View Post
    Since the title of this thread is "circular fifo", that implies an array or vector of nodes used as a circular buffer, or a circular linked list of fixed size. The example code uses a linked list, but its a conventional linked list and not a circular one.
    Actually, I change the approach from Linked list to array. But , still I am facing the same problem to assign the address to the struct data members.
    I have this struct
    Code:
     struct fifo{
       int count;
       int front;
       int rear;
       int items[max];
    } q;
    In Core 1, I am trying to initialize the address at say, 0XFFFF, but I am getting the l value error. I tried to solve it by Googling but none of them worked ..
    Code:
    int *ptr;
    ptr = (unsigned int *) 0xFFFF;
    &(q->front) = ptr;  //lvalue error
    Error:
    error: lvalue required as left operand of assignment
    &(q->front) = ptr;


    Please advice to solve this address assignment issues

  9. #9
    Registered User
    Join Date
    Apr 2013
    Posts
    1,656
    Instead of using pointers, just use front and rear as indexes to items. Since you have a count, you can initialize both front and rear to zero. Since front is only used by one thread, and rear by the other thread, you only need to protect count with a mutex. You may want to use a semaphore to wait for a non-empty fifo. After adding or removing an item from the fifo, advance the indexes modulo max, such as front = (front+1)%max.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. FIFO queue vs Link List
    By DeeMan in forum C Programming
    Replies: 8
    Last Post: 02-16-2013, 08:29 PM
  2. Priority queue and FIFO
    By Elysia in forum C++ Programming
    Replies: 12
    Last Post: 02-29-2012, 02:32 PM
  3. Help with FIFO queue
    By Martin_T in forum C Programming
    Replies: 10
    Last Post: 11-08-2009, 10:30 AM
  4. understanding queue FIFO
    By arastoo.s in forum C Programming
    Replies: 6
    Last Post: 08-18-2009, 10:16 AM
  5. Help with FIFO QUEUE
    By jackfraust in forum C++ Programming
    Replies: 23
    Last Post: 04-03-2009, 08:17 AM

Tags for this Thread