r42@gandalf: fugalh | 2006-06-07 17:08:39 -0600
[ardour.git] / libs / pbd3 / pbd / lock_free_fifo.h
1 /*
2     Copyright (C) 2000 Paul Barton-Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18     $Id$
19 */
20
21 #ifndef __pbd_lockfree_fifo_h__
22 #define __pbd_lockfree_fifo_h__
23
24 #include <sys/types.h>
25 #include <cstdlib>
26
27 template<class T>
28 class LockFreeFIFO 
29 {
30 public:
31     LockFreeFIFO (int sz) {
32             size = sz;
33             push_ptr = 0;
34             pop_ptr = 0;
35             buf = new T[size];
36     };
37
38     virtual ~LockFreeFIFO() { 
39             delete [] buf;
40     }
41                   
42
43     int pop (T& r) { 
44             if (pop_ptr == push_ptr) {
45                     return -1;
46             } else {
47                     r = buf[pop_ptr];
48                     pop_ptr++; 
49                     if (pop_ptr >= size) {
50                             pop_ptr = 0;
51                     }
52                     return 0;
53             }
54     }
55
56     int top (T& r) { 
57             if (pop_ptr == push_ptr) {
58                     return -1;
59             } else {
60                     r = buf[pop_ptr]; 
61                     return 0;
62             }
63     }
64
65     int push (T& t) { 
66             if ((size_t) abs (static_cast<int>(push_ptr - pop_ptr)) < size) {
67                     buf[push_ptr] = t;
68                     push_ptr++;
69                     if (push_ptr >= size) {
70                             push_ptr = 0;
71                     }
72                     return 0;
73             } else {
74                     return -1;
75             }
76     }
77
78   protected:
79     T *buf;
80     volatile size_t push_ptr;
81     volatile size_t pop_ptr;
82     size_t size;
83 };
84
85
86 #endif /* __pbd_lockfree_fifo_h__ */