Imported Upstream version 3.2.2
[debian/gnuradio] / gcell / lib / runtime / gc_jd_queue.c
1 /* -*- c -*- */
2 /*
3  * Copyright 2007 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #include <gcell/gc_jd_queue.h>
23 #include <gcell/memory_barrier.h>
24 #include <mutex_init.h>
25 #include <mutex_lock.h>
26 #include <mutex_unlock.h>
27
28 void 
29 gc_jd_queue_init(gc_jd_queue_t *q)
30 {
31   _mutex_init(ptr_to_ea(&q->mutex));
32   q->head = 0;
33   q->tail = 0;
34   smp_wmb();
35 }
36   
37 void
38 gc_jd_queue_enqueue(gc_jd_queue_t *q, gc_job_desc_t *item)
39 {
40   item->sys.next = 0;
41   _mutex_lock(ptr_to_ea(&q->mutex));
42   smp_rmb();            // import barrier
43
44   if (q->tail == 0){    // currently empty
45     q->tail = q->head = jdp_to_ea(item);
46   }
47   else {                // not empty, append
48     ea_to_jdp(q->tail)->sys.next = jdp_to_ea(item);
49     q->tail = jdp_to_ea(item);
50   }
51
52   smp_wmb();            // orders stores above before clearing of mutex
53   _mutex_unlock(ptr_to_ea(&q->mutex));
54 }
55
56 gc_job_desc_t *
57 gc_jd_queue_dequeue(gc_jd_queue_t *q)
58 {
59   _mutex_lock(ptr_to_ea(&q->mutex));
60   smp_rmb();            // import barrier
61   
62   gc_eaddr_t item_ea = q->head;
63   if (item_ea == 0){    // empty
64     _mutex_unlock(ptr_to_ea(&q->mutex));
65     return 0;
66   }
67
68   q->head = ea_to_jdp(item_ea)->sys.next;
69   if (q->head == 0)     // now emtpy
70     q->tail = 0;
71
72   gc_job_desc_t *item = ea_to_jdp(item_ea);
73   item->sys.next = 0;
74
75   smp_wmb();            // orders stores above before clearing of mutex
76   _mutex_unlock(ptr_to_ea(&q->mutex));
77   return item;
78 }