320 inline bool push(E t); |
320 inline bool push(E t); |
321 |
321 |
322 // Attempts to claim a task from the "local" end of the queue (the most |
322 // Attempts to claim a task from the "local" end of the queue (the most |
323 // recently pushed). If successful, returns true and sets t to the task; |
323 // recently pushed). If successful, returns true and sets t to the task; |
324 // otherwise, returns false (the queue is empty). |
324 // otherwise, returns false (the queue is empty). |
325 inline bool pop_local(E& t); |
325 inline bool pop_local(volatile E& t); |
326 |
326 |
327 // Like pop_local(), but uses the "global" end of the queue (the least |
327 // Like pop_local(), but uses the "global" end of the queue (the least |
328 // recently pushed). |
328 // recently pushed). |
329 bool pop_global(E& t); |
329 bool pop_global(volatile E& t); |
330 |
330 |
331 // Delete any resource associated with the queue. |
331 // Delete any resource associated with the queue. |
332 ~GenericTaskQueue(); |
332 ~GenericTaskQueue(); |
333 |
333 |
334 // apply the closure to all elements in the task queue |
334 // apply the closure to all elements in the task queue |
422 assert(dirty_size(localBot, _age.top()) != N - 1, "sanity"); |
422 assert(dirty_size(localBot, _age.top()) != N - 1, "sanity"); |
423 return false; |
423 return false; |
424 } |
424 } |
425 |
425 |
426 template<class E, MEMFLAGS F, unsigned int N> |
426 template<class E, MEMFLAGS F, unsigned int N> |
427 bool GenericTaskQueue<E, F, N>::pop_global(E& t) { |
427 bool GenericTaskQueue<E, F, N>::pop_global(volatile E& t) { |
428 Age oldAge = _age.get(); |
428 Age oldAge = _age.get(); |
429 // Architectures with weak memory model require a barrier here |
429 // Architectures with weak memory model require a barrier here |
430 // to guarantee that bottom is not older than age, |
430 // to guarantee that bottom is not older than age, |
431 // which is crucial for the correctness of the algorithm. |
431 // which is crucial for the correctness of the algorithm. |
432 #if !(defined SPARC || defined IA32 || defined AMD64) |
432 #if !(defined SPARC || defined IA32 || defined AMD64) |
699 return push_slow(t, dirty_n_elems); |
699 return push_slow(t, dirty_n_elems); |
700 } |
700 } |
701 } |
701 } |
702 |
702 |
703 template<class E, MEMFLAGS F, unsigned int N> inline bool |
703 template<class E, MEMFLAGS F, unsigned int N> inline bool |
704 GenericTaskQueue<E, F, N>::pop_local(E& t) { |
704 GenericTaskQueue<E, F, N>::pop_local(volatile E& t) { |
705 uint localBot = _bottom; |
705 uint localBot = _bottom; |
706 // This value cannot be N-1. That can only occur as a result of |
706 // This value cannot be N-1. That can only occur as a result of |
707 // the assignment to bottom in this method. If it does, this method |
707 // the assignment to bottom in this method. If it does, this method |
708 // resets the size to 0 before the next call (which is sequential, |
708 // resets the size to 0 before the next call (which is sequential, |
709 // since this is pop_local.) |
709 // since this is pop_local.) |