Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef _GLIBCXX_PARALLEL_QUEUE_H
00033 #define _GLIBCXX_PARALLEL_QUEUE_H 1
00034
00035 #include <parallel/types.h>
00036 #include <parallel/base.h>
00037 #include <parallel/compatibility.h>
00038
00039
00040 #define _GLIBCXX_VOLATILE volatile
00041
00042 namespace __gnu_parallel
00043 {
00044
00045
00046
00047
00048
00049
00050
00051 template<typename _Tp>
00052 class _RestrictedBoundedConcurrentQueue
00053 {
00054 private:
00055
00056 _Tp* _M_base;
00057
00058
00059 _SequenceIndex _M_max_size;
00060
00061
00062
00063 _GLIBCXX_VOLATILE _CASable _M_borders;
00064
00065 public:
00066
00067
00068 _RestrictedBoundedConcurrentQueue(_SequenceIndex __max_size)
00069 {
00070 _M_max_size = __max_size;
00071 _M_base = new _Tp[__max_size];
00072 _M_borders = __encode2(0, 0);
00073 #pragma omp flush
00074 }
00075
00076
00077 ~_RestrictedBoundedConcurrentQueue()
00078 { delete[] _M_base; }
00079
00080
00081
00082 void
00083 push_front(const _Tp& __t)
00084 {
00085 _CASable __former_borders = _M_borders;
00086 int __former_front, __former_back;
00087 __decode2(__former_borders, __former_front, __former_back);
00088 *(_M_base + __former_front % _M_max_size) = __t;
00089 #if _GLIBCXX_ASSERTIONS
00090
00091 _GLIBCXX_PARALLEL_ASSERT(((__former_front + 1) - __former_back)
00092 <= _M_max_size);
00093 #endif
00094 __fetch_and_add(&_M_borders, __encode2(1, 0));
00095 }
00096
00097
00098
00099 bool
00100 pop_front(_Tp& __t)
00101 {
00102 int __former_front, __former_back;
00103 #pragma omp flush
00104 __decode2(_M_borders, __former_front, __former_back);
00105 while (__former_front > __former_back)
00106 {
00107
00108 _CASable __former_borders = __encode2(__former_front,
00109 __former_back);
00110 _CASable __new_borders = __encode2(__former_front - 1,
00111 __former_back);
00112 if (__compare_and_swap(&_M_borders, __former_borders,
00113 __new_borders))
00114 {
00115 __t = *(_M_base + (__former_front - 1) % _M_max_size);
00116 return true;
00117 }
00118 #pragma omp flush
00119 __decode2(_M_borders, __former_front, __former_back);
00120 }
00121 return false;
00122 }
00123
00124
00125
00126 bool
00127 pop_back(_Tp& __t)
00128 {
00129 int __former_front, __former_back;
00130 #pragma omp flush
00131 __decode2(_M_borders, __former_front, __former_back);
00132 while (__former_front > __former_back)
00133 {
00134
00135 _CASable __former_borders = __encode2(__former_front,
00136 __former_back);
00137 _CASable __new_borders = __encode2(__former_front,
00138 __former_back + 1);
00139 if (__compare_and_swap(&_M_borders, __former_borders,
00140 __new_borders))
00141 {
00142 __t = *(_M_base + __former_back % _M_max_size);
00143 return true;
00144 }
00145 #pragma omp flush
00146 __decode2(_M_borders, __former_front, __former_back);
00147 }
00148 return false;
00149 }
00150 };
00151 }
00152
00153 #undef _GLIBCXX_VOLATILE
00154
00155 #endif