_aggregator_internal.h

00001 /*
00002     Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
00003 
00004     The source code contained or described herein and all documents related
00005     to the source code ("Material") are owned by Intel Corporation or its
00006     suppliers or licensors.  Title to the Material remains with Intel
00007     Corporation or its suppliers and licensors.  The Material is protected
00008     by worldwide copyright laws and treaty provisions.  No part of the
00009     Material may be used, copied, reproduced, modified, published, uploaded,
00010     posted, transmitted, distributed, or disclosed in any way without
00011     Intel's prior express written permission.
00012 
00013     No license under any patent, copyright, trade secret or other
00014     intellectual property right is granted to or conferred upon you by
00015     disclosure or delivery of the Materials, either expressly, by
00016     implication, inducement, estoppel or otherwise.  Any license under such
00017     intellectual property rights must be express and approved by Intel in
00018     writing.
00019 */
00020 
00021 #ifndef __TBB_aggregator_internal_H
00022 #define __TBB_aggregator_internal_H
00023 
00024 #include "atomic.h"
00025 #include "tbb_profiling.h"
00026 
00027 namespace tbb {
00028 namespace interface6 {
00029 namespace internal {
00030 
00031 using namespace tbb::internal;
00032 
00034 template <typename Derived>
00035 class aggregated_operation {
00036  public:
00037     uintptr_t status;
00038     Derived *next;
00039     aggregated_operation() : status(0), next(NULL) {}
00040 };
00041 
00043 
00048  template < typename handler_type, typename operation_type >
00049 class aggregator {
00050  public:
00051     aggregator() : handler_busy(false) { pending_operations = NULL; }
00052     ~aggregator() {}
00053 
00054     void initialize_handler(handler_type h) { handle_operations = h; }
00055 
00057 
00059     void execute(operation_type *op) {
00060         operation_type *res;
00061 
00062         // ITT note: &(op->status) tag is used to cover accesses to this op node. This
00063         // thread has created the operation, and now releases it so that the handler
00064         // thread may handle the associated operation w/o triggering a race condition;
00065         // thus this tag will be acquired just before the operation is handled in the
00066         // handle_operations functor.
00067         call_itt_notify(releasing, &(op->status));
00068         // insert the operation in the queue
00069         do {
00070             // ITT may flag the following line as a race; it is a false positive:
00071             // This is an atomic read; we don't provide itt_hide_load_word for atomics
00072             op->next = res = pending_operations; // NOT A RACE 
00073         } while (pending_operations.compare_and_swap(op, res) != res);
00074         if (!res) { // first in the list; handle the operations
00075             // ITT note: &pending_operations tag covers access to the handler_busy flag,
00076             // which this waiting handler thread will try to set before entering
00077             // handle_operations.
00078             call_itt_notify(acquired, &pending_operations);
00079             start_handle_operations();
00080             __TBB_ASSERT(op->status, NULL);
00081         }
00082         else { // not first; wait for op to be ready
00083             call_itt_notify(prepare, &(op->status));
00084             spin_wait_while_eq(op->status, uintptr_t(0));
00085             itt_load_word_with_acquire(op->status);
00086         }
00087     }
00088 
00089  private:
00091     atomic<operation_type *> pending_operations;
00093     uintptr_t handler_busy;
00094     handler_type handle_operations;
00095 
00097     void start_handle_operations() {
00098         operation_type *op_list;
00099 
00100         // ITT note: &handler_busy tag covers access to pending_operations as it is passed
00101         // between active and waiting handlers.  Below, the waiting handler waits until
00102         // the active handler releases, and the waiting handler acquires &handler_busy as
00103         // it becomes the active_handler. The release point is at the end of this
00104         // function, when all operations in pending_operations have been handled by the
00105         // owner of this aggregator.
00106         call_itt_notify(prepare, &handler_busy);
00107         // get the handler_busy:
00108         // only one thread can possibly spin here at a time
00109         spin_wait_until_eq(handler_busy, uintptr_t(0));
00110         call_itt_notify(acquired, &handler_busy);
00111         // acquire fence not necessary here due to causality rule and surrounding atomics
00112         __TBB_store_with_release(handler_busy, uintptr_t(1));
00113 
00114         // ITT note: &pending_operations tag covers access to the handler_busy flag
00115         // itself. Capturing the state of the pending_operations signifies that
00116         // handler_busy has been set and a new active handler will now process that list's
00117         // operations.
00118         call_itt_notify(releasing, &pending_operations);
00119         // grab pending_operations
00120         op_list = pending_operations.fetch_and_store(NULL);
00121 
00122         // handle all the operations
00123         handle_operations(op_list);
00124 
00125         // release the handler
00126         itt_store_word_with_release(handler_busy, uintptr_t(0));
00127     }
00128 };
00129 
00130 } // namespace internal
00131 } // namespace interface6
00132 
00133 namespace internal {
00134     using interface6::internal::aggregated_operation;
00135     using interface6::internal::aggregator;
00136 } // namespace internal
00137 
00138 } // namespace tbb
00139 
00140 #endif

Copyright © 2005-2011 Intel Corporation. All Rights Reserved.

Intel, Pentium, Intel Xeon, Itanium, Intel XScale and VTune are registered trademarks or trademarks of Intel Corporation or its subsidiaries in the United States and other countries.

* Other names and brands may be claimed as the property of others.