task_arena.h

00001 /*
00002     Copyright 2005-2012 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_task_arena_H
00022 #define __TBB_task_arena_H
00023 
00024 #include "task.h"
00025 #include "tbb_exception.h"
00026 
00027 #if __TBB_TASK_ARENA
00028 
00029 namespace tbb {
00030 
00032 namespace internal {
00034 
00035     class arena;
00036     class task_scheduler_observer_v3;
00037 } // namespace internal
00039 
00040 namespace interface6 {
00042 namespace internal {
00043 using namespace tbb::internal;
00044 
00045 template<typename F>
00046 class enqueued_function_task : public task { // TODO: reuse from task_group?
00047     F my_func;
00048     /*override*/ task* execute() {
00049         my_func();
00050         return NULL;
00051     }
00052 public:
00053     enqueued_function_task ( const F& f ) : my_func(f) {}
00054 };
00055 
00056 class delegate_base : no_assign {
00057 public:
00058     virtual void run() = 0;
00059     virtual ~delegate_base() {}
00060 };
00061 
00062 template<typename F>
00063 class delegated_function : public delegate_base {
00064     F &my_func;
00065     /*override*/ void run() {
00066         my_func();
00067     }
00068 public:
00069     delegated_function ( F& f ) : my_func(f) {}
00070 };
00071 } // namespace internal
00073 
00080 class task_arena {
00081     friend class internal::task_scheduler_observer_v3;
00083     int my_max_concurrency;
00084 
00086     internal::arena* my_arena;
00087 
00088     // const methods help to optimize the !my_arena check TODO: check, IDEA: move to base-class?
00089     internal::arena* __TBB_EXPORTED_METHOD internal_initialize( int ) const;
00090     void __TBB_EXPORTED_METHOD internal_terminate( );
00091     void __TBB_EXPORTED_METHOD internal_enqueue( task&, intptr_t ) const;
00092     void __TBB_EXPORTED_METHOD internal_execute( internal::delegate_base& ) const;
00093     void __TBB_EXPORTED_METHOD internal_wait() const;
00094 
00095     inline void check_init() {
00096         if( !my_arena )
00097             my_arena = internal_initialize( my_max_concurrency );
00098     }
00099 
00100 public:
00102     static const int automatic = -1; // any value < 1 means 'automatic'
00103 
00105     task_arena(int max_concurrency = automatic)
00106         : my_max_concurrency(max_concurrency)
00107         , my_arena(0)
00108     {}
00109 
00111     task_arena(const task_arena &s)
00112         : my_max_concurrency(s.my_max_concurrency) // copy settings
00113         , my_arena(0) // but not the reference or instance
00114     {}
00115 
00118     ~task_arena() {
00119         internal_terminate();
00120     }
00121 
00124     template<typename F>
00125     void enqueue( const F& f ) {
00126         check_init();
00127         internal_enqueue( *new( task::allocate_root() ) internal::enqueued_function_task<F>(f), 0 );
00128     }
00129 
00130 #if __TBB_TASK_PRIORITY
00133     template<typename F>
00134     void enqueue( const F& f, priority_t p ) {
00135         __TBB_ASSERT( p == priority_low || p == priority_normal || p == priority_high, "Invalid priority level value" );
00136         check_init();
00137         internal_enqueue( *new( task::allocate_root() ) internal::enqueued_function_task<F>(f), (intptr_t)p );
00138     }
00139 #endif// __TBB_TASK_PRIORITY
00140 
00144     template<typename F>
00145     void execute(F& f) {
00146         check_init();
00147         internal::delegated_function<F> d(f);
00148         internal_execute( d );
00149     }
00150 
00154     template<typename F>
00155     void execute(const F& f) {
00156         check_init();
00157         internal::delegated_function<const F> d(f);
00158         internal_execute( d );
00159     }
00160 
00164     void wait_until_empty() {
00165         check_init();
00166         internal_wait();
00167     }
00168 
00170     inline void initialize(int max_concurrency) {
00171         my_max_concurrency = max_concurrency;
00172         __TBB_ASSERT( !my_arena, "task_arena was initialized already"); // TODO: throw?
00173         check_init();
00174     }
00175 
00177     static int __TBB_EXPORTED_FUNC current_slot();
00178 };
00179 
00180 } // namespace interfaceX
00181 
00182 using interface6::task_arena;
00183 
00184 } // namespace tbb
00185 
00186 #endif /* __TBB_TASK_ARENA */
00187 
00188 #endif /* __TBB_task_arena_H */

Copyright © 2005-2012 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.