27
28 #include "gc/shared/taskqueue.hpp"
29 #include "memory/allocation.inline.hpp"
30 #include "oops/oop.inline.hpp"
31 #include "runtime/atomic.hpp"
32 #include "runtime/orderAccess.inline.hpp"
33 #include "utilities/debug.hpp"
34 #include "utilities/stack.inline.hpp"
35
36 template <class T, MEMFLAGS F>
37 inline GenericTaskQueueSet<T, F>::GenericTaskQueueSet(int n) : _n(n) {
38 typedef T* GenericTaskQueuePtr;
39 _queues = NEW_C_HEAP_ARRAY(GenericTaskQueuePtr, n, F);
40 for (int i = 0; i < n; i++) {
41 _queues[i] = NULL;
42 }
43 }
44
45 template<class E, MEMFLAGS F, unsigned int N>
46 inline void GenericTaskQueue<E, F, N>::initialize() {
47 _elems = ArrayAllocator<E, F>::allocate(N);
48 }
49
50 template<class E, MEMFLAGS F, unsigned int N>
51 inline GenericTaskQueue<E, F, N>::~GenericTaskQueue() {
52 assert(false, "This code is currently never called");
53 ArrayAllocator<E, F>::free(const_cast<E*>(_elems), N);
54 }
55
56 template<class E, MEMFLAGS F, unsigned int N>
57 bool GenericTaskQueue<E, F, N>::push_slow(E t, uint dirty_n_elems) {
58 if (dirty_n_elems == N - 1) {
59 // Actually means 0, so do the push.
60 uint localBot = _bottom;
61 // g++ complains if the volatile result of the assignment is
62 // unused, so we cast the volatile away. We cannot cast directly
63 // to void, because gcc treats that as not using the result of the
64 // assignment. However, casting to E& means that we trigger an
65 // unused-value warning. So, we cast the E& to void.
66 (void)const_cast<E&>(_elems[localBot] = t);
67 OrderAccess::release_store(&_bottom, increment_index(localBot));
68 TASKQUEUE_STATS_ONLY(stats.record_push());
69 return true;
70 }
71 return false;
72 }
73
|
27
28 #include "gc/shared/taskqueue.hpp"
29 #include "memory/allocation.inline.hpp"
30 #include "oops/oop.inline.hpp"
31 #include "runtime/atomic.hpp"
32 #include "runtime/orderAccess.inline.hpp"
33 #include "utilities/debug.hpp"
34 #include "utilities/stack.inline.hpp"
35
36 template <class T, MEMFLAGS F>
37 inline GenericTaskQueueSet<T, F>::GenericTaskQueueSet(int n) : _n(n) {
38 typedef T* GenericTaskQueuePtr;
39 _queues = NEW_C_HEAP_ARRAY(GenericTaskQueuePtr, n, F);
40 for (int i = 0; i < n; i++) {
41 _queues[i] = NULL;
42 }
43 }
44
45 template<class E, MEMFLAGS F, unsigned int N>
46 inline void GenericTaskQueue<E, F, N>::initialize() {
47 _elems = ArrayAllocator<E>::allocate(N, F);
48 }
49
50 template<class E, MEMFLAGS F, unsigned int N>
51 inline GenericTaskQueue<E, F, N>::~GenericTaskQueue() {
52 assert(false, "This code is currently never called");
53 ArrayAllocator<E>::free(const_cast<E*>(_elems), N);
54 }
55
56 template<class E, MEMFLAGS F, unsigned int N>
57 bool GenericTaskQueue<E, F, N>::push_slow(E t, uint dirty_n_elems) {
58 if (dirty_n_elems == N - 1) {
59 // Actually means 0, so do the push.
60 uint localBot = _bottom;
61 // g++ complains if the volatile result of the assignment is
62 // unused, so we cast the volatile away. We cannot cast directly
63 // to void, because gcc treats that as not using the result of the
64 // assignment. However, casting to E& means that we trigger an
65 // unused-value warning. So, we cast the E& to void.
66 (void)const_cast<E&>(_elems[localBot] = t);
67 OrderAccess::release_store(&_bottom, increment_index(localBot));
68 TASKQUEUE_STATS_ONLY(stats.record_push());
69 return true;
70 }
71 return false;
72 }
73
|