Updated Sunset/Sunrise functions to latest PyEphem API
[debian/gnuradio] / gcell / src / lib / runtime / gc_jd_stack.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 "gc_jd_stack.h"
23 #include "memory_barrier.h"
24
25
26 void 
27 gc_jd_stack_init(gc_jd_stack_t *stack)
28 {
29   stack->top = 0;
30 }
31   
32
33 #ifdef __powerpc64__  // 64-bit mode
34
35 void 
36 gc_jd_stack_push(gc_jd_stack_t *stack, gc_job_desc_t *item)
37 {
38   gc_eaddr_t    top;
39   gc_eaddr_t    item_ea = ptr_to_ea(item);
40   unsigned int  done;
41
42   do {
43     top = __ldarx(&stack->top);
44     item->sys.next = top;
45     smp_wmb();        // order store of item->next before store of stack->top
46     done = __stdcx(&stack->top, item_ea);
47   } while (unlikely(done == 0));
48 }
49
50 gc_job_desc_t *
51 gc_jd_stack_pop(gc_jd_stack_t *stack)
52 {
53   gc_eaddr_t    s;
54   gc_eaddr_t    t;
55   unsigned int  done;
56
57   do {
58     s  = __ldarx(&stack->top);
59     if (s == 0)                 /* stack's empty */
60       return 0;
61     t = ((gc_job_desc_t *) ea_to_ptr(s))->sys.next;
62     done = __stdcx(&stack->top, t);
63   } while (unlikely(done == 0));
64
65   return ea_to_ptr(s);
66 }
67
68 #else  // 32-bit mode
69
70 /*
71  * In 32-bit mode, gc_eaddr's will have the top 32-bits zero.
72  * The ldarx/stdcx instructions aren't available in 32-bit mode,
73  * thus we use lwarx/stwcx on the low 32-bits of the 64-bit addresses.
74  * Since we're big-endian, the low 32-bits are at word offset 1.
75  */
76 void 
77 gc_jd_stack_push(gc_jd_stack_t *stack, gc_job_desc_t *item)
78 {
79   gc_eaddr_t    top;
80   unsigned int  done;
81
82   do {
83     top = __lwarx((int32_t *)(&stack->top) + 1);
84     item->sys.next = top;
85     smp_wmb();        // order store of item->sys.next before store of stack->top
86     done = __stwcx((int32_t *)(&stack->top) + 1, item);
87   } while (unlikely(done == 0));
88 }
89
90 gc_job_desc_t *
91 gc_jd_stack_pop(gc_jd_stack_t *stack)
92 {
93   gc_eaddr_t    s;
94   gc_eaddr_t    t;
95   unsigned int  done;
96
97   do {
98     s  = __lwarx((int32_t *)(&stack->top) + 1);
99     if (s == 0)                 /* stack's empty */
100       return 0;
101     t = ((gc_job_desc_t *) ea_to_ptr(s))->sys.next;
102     done = __stwcx((int32_t *)(&stack->top) + 1, (uint32_t) t);
103   } while (unlikely(done == 0));
104
105   return ea_to_ptr(s);
106 }
107
108 #endif