- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

# task.h

    00001 /*
    00002     Copyright 2005-2012 Intel Corporation.  All Rights Reserved.
    00003
    00004     This file is part of Threading Building Blocks.
    00005
    00006     Threading Building Blocks is free software; you can redistribute it
    00007     and/or modify it under the terms of the GNU General Public License
    00008     version 2 as published by the Free Software Foundation.
    00009
    00010     Threading Building Blocks is distributed in the hope that it will be
    00011     useful, but WITHOUT ANY WARRANTY; without even the implied warranty
    00012     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00013     GNU General Public License for more details.
    00014
    00015     You should have received a copy of the GNU General Public License
    00016     along with Threading Building Blocks; if not, write to the Free Software
    00017     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    00018
    00019     As a special exception, you may use this file as part of a free software
    00020     library without restriction.  Specifically, if other files instantiate
    00021     templates or use macros or inline functions from this file, or you compile
    00022     this file and link it with other files to produce an executable, this
    00023     file does not by itself cause the resulting executable to be covered by
    00024     the GNU General Public License.  This exception does not however
    00025     invalidate any other reasons why the executable file might be covered by
    00026     the GNU General Public License.
    00027 */
    00028
    00029 #ifndef __TBB_task_H
    00030 #define __TBB_task_H
    00031
    00032 #include "tbb_stddef.h"
    00033 #include "tbb_machine.h"
    00034 #include <climits>
    00035
    00036 typedef struct ___itt_caller *__itt_caller;
    00037
    00038 namespace tbb {
    00039
    00040 class task;
    00041 class task_list;
    00042
    00043 #if __TBB_TASK_GROUP_CONTEXT
    00044 class task_group_context;
    00045 #endif /* __TBB_TASK_GROUP_CONTEXT */
    00046
    00047 // MSVC does not allow taking the address of a member that was defined
    00048 // privately in task_base and made public in class task via a using declaration.
    00049 #if _MSC_VER || (__GNUC__==3 && __GNUC_MINOR__<3)
    00050 #define __TBB_TASK_BASE_ACCESS public
    00051 #else
    00052 #define __TBB_TASK_BASE_ACCESS private
    00053 #endif
    00054
    00055 namespace internal {
    00056
    00057     class allocate_additional_child_of_proxy: no_assign {
    00059         task* self;
    00060         task& parent;
    00061     public:
    00062         explicit allocate_additional_child_of_proxy( task& parent_ ) : self(NULL), parent(parent_) {}
    00063         task& __TBB_EXPORTED_METHOD allocate( size_t size ) const;
    00064         void __TBB_EXPORTED_METHOD free( task& ) const;
    00065     };
    00066
    00067 }
    00068
    00069 namespace interface5 {
    00070     namespace internal {
    00072
    00077         class task_base: tbb::internal::no_copy {
    00078         __TBB_TASK_BASE_ACCESS:
    00079             friend class tbb::task;
    00080
    00082             static void spawn( task& t );
    00083
    00085             static void spawn( task_list& list );
    00086
    00088
    00090             static tbb::internal::allocate_additional_child_of_proxy allocate_additional_child_of( task& t ) {
    00091                 return tbb::internal::allocate_additional_child_of_proxy(t);
    00092             }
    00093
    00095
    00099             static void __TBB_EXPORTED_FUNC destroy( task& victim );
    00100         };
    00101     } // internal
    00102 } // interface5
    00103
    00105 namespace internal {
    00106
    00107     class scheduler: no_copy {
    00108     public:
    00110         virtual void spawn( task& first, task*& next ) = 0;
    00111
    00113         virtual void wait_for_all( task& parent, task* child ) = 0;
    00114
    00116         virtual void spawn_root_and_wait( task& first, task*& next ) = 0;
    00117
    00119         //  Have to have it just to shut up overzealous compilation warnings
    00120         virtual ~scheduler() = 0;
    00121
    00123         virtual void enqueue( task& t, void* reserved ) = 0;
    00124     };
    00125
    00127
    00128     typedef intptr_t reference_count;
    00129
    00131     typedef unsigned short affinity_id;
    00132
    00133 #if __TBB_TASK_GROUP_CONTEXT
    00134     class generic_scheduler;
    00135
    00136     struct context_list_node_t {
    00137         context_list_node_t *my_prev,
    00138                             *my_next;
    00139     };
    00140
    00141     class allocate_root_with_context_proxy: no_assign {
    00142         task_group_context& my_context;
    00143     public:
    00144         allocate_root_with_context_proxy ( task_group_context& ctx ) : my_context(ctx) {}
    00145         task& __TBB_EXPORTED_METHOD allocate( size_t size ) const;
    00146         void __TBB_EXPORTED_METHOD free( task& ) const;
    00147     };
    00148 #endif /* __TBB_TASK_GROUP_CONTEXT */
    00149
    00150     class allocate_root_proxy: no_assign {
    00151     public:
    00152         static task& __TBB_EXPORTED_FUNC allocate( size_t size );
    00153         static void __TBB_EXPORTED_FUNC free( task& );
    00154     };
    00155
    00156     class allocate_continuation_proxy: no_assign {
    00157     public:
    00158         task& __TBB_EXPORTED_METHOD allocate( size_t size ) const;
    00159         void __TBB_EXPORTED_METHOD free( task& ) const;
    00160     };
    00161
    00162     class allocate_child_proxy: no_assign {
    00163     public:
    00164         task& __TBB_EXPORTED_METHOD allocate( size_t size ) const;
    00165         void __TBB_EXPORTED_METHOD free( task& ) const;
    00166     };
    00167
    00169
    00180     class task_prefix {
    00181     private:
    00182         friend class tbb::task;
    00183         friend class tbb::interface5::internal::task_base;
    00184         friend class tbb::task_list;
    00185         friend class internal::scheduler;
    00186         friend class internal::allocate_root_proxy;
    00187         friend class internal::allocate_child_proxy;
    00188         friend class internal::allocate_continuation_proxy;
    00189         friend class internal::allocate_additional_child_of_proxy;
    00190
    00191 #if __TBB_TASK_GROUP_CONTEXT
    00193
    00196         task_group_context  *context;
    00197 #endif /* __TBB_TASK_GROUP_CONTEXT */
    00198
    00200
    00205         scheduler* origin;
    00206
    00207 #if __TBB_TASK_PRIORITY
    00208         union {
    00209 #endif /* __TBB_TASK_PRIORITY */
    00211
    00213         scheduler* owner;
    00214
    00215 #if __TBB_TASK_PRIORITY
    00217
    00218         task* next_offloaded;
    00219         };
    00220 #endif /* __TBB_TASK_PRIORITY */
    00221
    00223
    00226         tbb::task* parent;
    00227
    00229
    00233         __TBB_atomic reference_count ref_count;
    00234
    00236
    00238         int depth;
    00239
    00241
    00242         unsigned char state;
    00243
    00245
    00251         unsigned char extra_state;
    00252
    00253         affinity_id affinity;
    00254
    00256         tbb::task* next;
    00257
    00259         tbb::task& task() {return *reinterpret_cast<tbb::task*>(this+1);}
    00260     };
    00261
    00262 } // namespace internal
    00264
    00265 #if __TBB_TASK_GROUP_CONTEXT
    00266
    00267 #if __TBB_TASK_PRIORITY
    00268 namespace internal {
    00269     static const int priority_stride_v4 = INT_MAX / 4;
    00270 }
    00271
    00272 enum priority_t {
    00273     priority_normal = internal::priority_stride_v4 * 2,
    00274     priority_low = priority_normal - internal::priority_stride_v4,
    00275     priority_high = priority_normal + internal::priority_stride_v4
    00276 };
    00277
    00278 #endif /* __TBB_TASK_PRIORITY */
    00279
    00280 #if TBB_USE_CAPTURED_EXCEPTION
    00281     class tbb_exception;
    00282 #else
    00283     namespace internal {
    00284         class tbb_exception_ptr;
    00285     }
    00286 #endif /* !TBB_USE_CAPTURED_EXCEPTION */
    00287
    00288 class task_scheduler_init;
    00289
    00291
    00311 class task_group_context : internal::no_copy {
    00312 private:
    00313     friend class internal::generic_scheduler;
    00314     friend class task_scheduler_init;
    00315
    00316 #if TBB_USE_CAPTURED_EXCEPTION
    00317     typedef tbb_exception exception_container_type;
    00318 #else
    00319     typedef internal::tbb_exception_ptr exception_container_type;
    00320 #endif
    00321
    00322     enum version_traits_word_layout {
    00323         traits_offset = 16,
    00324         version_mask = 0xFFFF,
    00325         traits_mask = 0xFFFFul << traits_offset
    00326     };
    00327
    00328 public:
    00329     enum kind_type {
    00330         isolated,
    00331         bound
    00332     };
    00333
    00334     enum traits_type {
    00335         exact_exception = 0x0001ul << traits_offset,
    00336         concurrent_wait = 0x0004ul << traits_offset,
    00337 #if TBB_USE_CAPTURED_EXCEPTION
    00338         default_traits = 0
    00339 #else
    00340         default_traits = exact_exception
    00341 #endif /* !TBB_USE_CAPTURED_EXCEPTION */
    00342     };
    00343
    00344 private:
    00345     enum state {
    00346         may_have_children = 1
    00347     };
    00348
    00349     union {
    00351         kind_type my_kind;
    00352         uintptr_t _my_kind_aligner;
    00353     };
    00354
    00356     task_group_context *my_parent;
    00357
    00359
    00361     internal::context_list_node_t my_node;
    00362
    00364     __itt_caller itt_caller;
    00365
    00367
    00370     char _leading_padding[internal::NFS_MaxLineSize
    00371                           - 2 * sizeof(uintptr_t)- sizeof(void*) - sizeof(internal::context_list_node_t)
    00372                           - sizeof(__itt_caller)];
    00373
    00375     uintptr_t my_cancellation_requested;
    00376
    00378
    00381     uintptr_t  my_version_and_traits;
    00382
    00384     exception_container_type *my_exception;
    00385
    00387     internal::generic_scheduler *my_owner;
    00388
    00390     uintptr_t my_state;
    00391
    00392 #if __TBB_TASK_PRIORITY
    00394     intptr_t my_priority;
    00395 #endif /* __TBB_TASK_PRIORITY */
    00396
    00398
    00399     char _trailing_padding[internal::NFS_MaxLineSize - 2 * sizeof(uintptr_t) - 2 * sizeof(void*)
    00400 #if __TBB_TASK_PRIORITY
    00401                             - sizeof(intptr_t)
    00402 #endif /* __TBB_TASK_PRIORITY */
    00403                           ];
    00404
    00405 public:
    00407
    00435     task_group_context ( kind_type relation_with_parent = bound,
    00436                          uintptr_t traits = default_traits )
    00437         : my_kind(relation_with_parent)
    00438         , my_version_and_traits(1 | traits)
    00439     {
    00440         init();
    00441     }
    00442
    00443     __TBB_EXPORTED_METHOD ~task_group_context ();
    00444
    00446
    00453     void __TBB_EXPORTED_METHOD reset ();
    00454
    00456
    00463     bool __TBB_EXPORTED_METHOD cancel_group_execution ();
    00464
    00466     bool __TBB_EXPORTED_METHOD is_group_execution_cancelled () const;
    00467
    00469
    00475     void __TBB_EXPORTED_METHOD register_pending_exception ();
    00476
    00477 #if __TBB_TASK_PRIORITY
    00479     void set_priority ( priority_t );
    00480
    00482     priority_t priority () const;
    00483 #endif /* __TBB_TASK_PRIORITY */
    00484
    00485 protected:
    00487
    00488     void __TBB_EXPORTED_METHOD init ();
    00489
    00490 private:
    00491     friend class task;
    00492     friend class internal::allocate_root_with_context_proxy;
    00493
    00494     static const kind_type binding_required = bound;
    00495     static const kind_type binding_completed = kind_type(bound+1);
    00496     static const kind_type detached = kind_type(binding_completed+1);
    00497     static const kind_type dying = kind_type(detached+1);
    00498
    00500
    00502     template <typename T>
    00503     void propagate_state_from_ancestors ( T task_group_context::*mptr_state, T new_state );
    00504
    00506     inline void finish_initialization ( internal::generic_scheduler *local_sched );
    00507
    00509     void bind_to ( internal::generic_scheduler *local_sched );
    00510
    00512     void register_with ( internal::generic_scheduler *local_sched );
    00513
    00514 }; // class task_group_context
    00515
    00516 #endif /* __TBB_TASK_GROUP_CONTEXT */
    00517
    00519
    00520 class task: __TBB_TASK_BASE_ACCESS interface5::internal::task_base {
    00521
    00523     void __TBB_EXPORTED_METHOD internal_set_ref_count( int count );
    00524
    00526     internal::reference_count __TBB_EXPORTED_METHOD internal_decrement_ref_count();
    00527
    00528 protected:
    00530     task() {prefix().extra_state=1;}
    00531
    00532 public:
    00534     virtual ~task() {}
    00535
    00537     virtual task* execute() = 0;
    00538
    00540     enum state_type {
    00542         executing,
    00544         reexecute,
    00546         ready,
    00548         allocated,
    00550         freed,
    00552         recycle
    00553     };
    00554
    00555     //------------------------------------------------------------------------
    00556     // Allocating tasks
    00557     //------------------------------------------------------------------------
    00558
    00560     static internal::allocate_root_proxy allocate_root() {
    00561         return internal::allocate_root_proxy();
    00562     }
    00563
    00564 #if __TBB_TASK_GROUP_CONTEXT
    00566     static internal::allocate_root_with_context_proxy allocate_root( task_group_context& ctx ) {
    00567         return internal::allocate_root_with_context_proxy(ctx);
    00568     }
    00569 #endif /* __TBB_TASK_GROUP_CONTEXT */
    00570
    00572
    00573     internal::allocate_continuation_proxy& allocate_continuation() {
    00574         return *reinterpret_cast<internal::allocate_continuation_proxy*>(this);
    00575     }
    00576
    00578     internal::allocate_child_proxy& allocate_child() {
    00579         return *reinterpret_cast<internal::allocate_child_proxy*>(this);
    00580     }
    00581
    00583     using task_base::allocate_additional_child_of;
    00584
    00585 #if __TBB_DEPRECATED_TASK_INTERFACE
    00587
    00591     void __TBB_EXPORTED_METHOD destroy( task& t );
    00592 #else /* !__TBB_DEPRECATED_TASK_INTERFACE */
    00594     using task_base::destroy;
    00595 #endif /* !__TBB_DEPRECATED_TASK_INTERFACE */
    00596
    00597     //------------------------------------------------------------------------
    00598     // Recycling of tasks
    00599     //------------------------------------------------------------------------
    00600
    00602
    00608     void recycle_as_continuation() {
    00609         __TBB_ASSERT( prefix().state==executing, "execute not running?" );
    00610         prefix().state = allocated;
    00611     }
    00612
    00614
    00616     void recycle_as_safe_continuation() {
    00617         __TBB_ASSERT( prefix().state==executing, "execute not running?" );
    00618         prefix().state = recycle;
    00619     }
    00620
    00622     void recycle_as_child_of( task& new_parent ) {
    00623         internal::task_prefix& p = prefix();
    00624         __TBB_ASSERT( prefix().state==executing||prefix().state==allocated, "execute not running, or already recycled" );
    00625         __TBB_ASSERT( prefix().ref_count==0, "no child tasks allowed when recycled as a child" );
    00626         __TBB_ASSERT( p.parent==NULL, "parent must be null" );
    00627         __TBB_ASSERT( new_parent.prefix().state<=recycle, "corrupt parent's state" );
    00628         __TBB_ASSERT( new_parent.prefix().state!=freed, "parent already freed" );
    00629         p.state = allocated;
    00630         p.parent = &new_parent;
    00631 #if __TBB_TASK_GROUP_CONTEXT
    00632         p.context = new_parent.prefix().context;
    00633 #endif /* __TBB_TASK_GROUP_CONTEXT */
    00634     }
    00635
    00637
    00638     void recycle_to_reexecute() {
    00639         __TBB_ASSERT( prefix().state==executing, "execute not running, or already recycled" );
    00640         __TBB_ASSERT( prefix().ref_count==0, "no child tasks allowed when recycled for reexecution" );
    00641         prefix().state = reexecute;
    00642     }
    00643
    00644     // All depth-related methods are obsolete, and are retained for the sake
    00645     // of backward source compatibility only
    00646     intptr_t depth() const {return 0;}
    00647     void set_depth( intptr_t ) {}
    00648     void add_to_depth( int ) {}
    00649
    00650
    00651     //------------------------------------------------------------------------
    00652     // Spawning and blocking
    00653     //------------------------------------------------------------------------
    00654
    00656     void set_ref_count( int count ) {
    00657 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
    00658         internal_set_ref_count(count);
    00659 #else
    00660         prefix().ref_count = count;
    00661 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
    00662     }
    00663
    00665
    00666     void increment_ref_count() {
    00667         __TBB_FetchAndIncrementWacquire( &prefix().ref_count );
    00668     }
    00669
    00671
    00672     int decrement_ref_count() {
    00673 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
    00674         return int(internal_decrement_ref_count());
    00675 #else
    00676         return int(__TBB_FetchAndDecrementWrelease( &prefix().ref_count ))-1;
    00677 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
    00678     }
    00679
    00681     using task_base::spawn;
    00682
    00684     void spawn_and_wait_for_all( task& child ) {
    00685         prefix().owner->wait_for_all( *this, &child );
    00686     }
    00687
    00689     void __TBB_EXPORTED_METHOD spawn_and_wait_for_all( task_list& list );
    00690
    00692     static void spawn_root_and_wait( task& root ) {
    00693         root.prefix().owner->spawn_root_and_wait( root, root.prefix().next );
    00694     }
    00695
    00697
    00699     static void spawn_root_and_wait( task_list& root_list );
    00700
    00702
    00703     void wait_for_all() {
    00704         prefix().owner->wait_for_all( *this, NULL );
    00705     }
    00706
    00708 #if __TBB_TASK_PRIORITY
    00709
    00719 #endif /* __TBB_TASK_PRIORITY */
    00720     static void enqueue( task& t ) {
    00721         t.prefix().owner->enqueue( t, NULL );
    00722     }
    00723
    00724 #if __TBB_TASK_PRIORITY
    00726     static void enqueue( task& t, priority_t p ) {
    00727         __TBB_ASSERT( p == priority_low || p == priority_normal || p == priority_high, "Invalid priority level value" );
    00728         t.prefix().owner->enqueue( t, (void*)p );
    00729     }
    00730 #endif /* __TBB_TASK_PRIORITY */
    00731
    00733     static task& __TBB_EXPORTED_FUNC self();
    00734
    00736     task* parent() const {return prefix().parent;}
    00737
    00739     void set_parent(task* p) {
    00740 #if __TBB_TASK_GROUP_CONTEXT
    00741         __TBB_ASSERT(prefix().context == p->prefix().context, "The tasks must be in the same context");
    00742 #endif
    00743         prefix().parent = p;
    00744     }
    00745
    00746 #if __TBB_TASK_GROUP_CONTEXT
    00748
    00749     task_group_context* context() {return prefix().context;}
    00750
    00752     task_group_context* group () { return prefix().context; }
    00753 #endif /* __TBB_TASK_GROUP_CONTEXT */
    00754
    00756     bool is_stolen_task() const {
    00757         return (prefix().extra_state & 0x80)!=0;
    00758     }
    00759
    00760     //------------------------------------------------------------------------
    00761     // Debugging
    00762     //------------------------------------------------------------------------
    00763
    00765     state_type state() const {return state_type(prefix().state);}
    00766
    00768     int ref_count() const {
    00769 #if TBB_USE_ASSERT
    00770         internal::reference_count ref_count_ = prefix().ref_count;
    00771         __TBB_ASSERT( ref_count_==int(ref_count_), "integer overflow error");
    00772 #endif
    00773         return int(prefix().ref_count);
    00774     }
    00775
    00777     bool __TBB_EXPORTED_METHOD is_owned_by_current_thread() const;
    00778
    00779     //------------------------------------------------------------------------
    00780     // Affinity
    00781     //------------------------------------------------------------------------
    00782
    00784
    00785     typedef internal::affinity_id affinity_id;
    00786
    00788     void set_affinity( affinity_id id ) {prefix().affinity = id;}
    00789
    00791     affinity_id affinity() const {return prefix().affinity;}
    00792
    00794
    00798     virtual void __TBB_EXPORTED_METHOD note_affinity( affinity_id id );
    00799
    00800 #if __TBB_TASK_GROUP_CONTEXT
    00802
    00812     void __TBB_EXPORTED_METHOD change_group ( task_group_context& ctx );
    00813
    00815
    00816     bool cancel_group_execution () { return prefix().context->cancel_group_execution(); }
    00817
    00819     bool is_cancelled () const { return prefix().context->is_group_execution_cancelled(); }
    00820 #endif /* __TBB_TASK_GROUP_CONTEXT */
    00821
    00822 #if __TBB_TASK_PRIORITY
    00824     void set_group_priority ( priority_t p ) {  prefix().context->set_priority(p); }
    00825
    00827     priority_t group_priority () const { return prefix().context->priority(); }
    00828
    00829 #endif /* __TBB_TASK_PRIORITY */
    00830
    00831 private:
    00832     friend class interface5::internal::task_base;
    00833     friend class task_list;
    00834     friend class internal::scheduler;
    00835     friend class internal::allocate_root_proxy;
    00836 #if __TBB_TASK_GROUP_CONTEXT
    00837     friend class internal::allocate_root_with_context_proxy;
    00838 #endif /* __TBB_TASK_GROUP_CONTEXT */
    00839     friend class internal::allocate_continuation_proxy;
    00840     friend class internal::allocate_child_proxy;
    00841     friend class internal::allocate_additional_child_of_proxy;
    00842
    00844
    00845     internal::task_prefix& prefix( internal::version_tag* = NULL ) const {
    00846         return reinterpret_cast<internal::task_prefix*>(const_cast<task*>(this))[-1];
    00847     }
    00848 }; // class task
    00849
    00851
    00852 class empty_task: public task {
    00853     /*override*/ task* execute() {
    00854         return NULL;
    00855     }
    00856 };
    00857
    00859
    00861 class task_list: internal::no_copy {
    00862 private:
    00863     task* first;
    00864     task** next_ptr;
    00865     friend class task;
    00866     friend class interface5::internal::task_base;
    00867 public:
    00869     task_list() : first(NULL), next_ptr(&first) {}
    00870
    00872     ~task_list() {}
    00873
    00875     bool empty() const {return !first;}
    00876
    00878     void push_back( task& task ) {
    00879         task.prefix().next = NULL;
    00880         *next_ptr = &task;
    00881         next_ptr = &task.prefix().next;
    00882     }
    00883
    00885     task& pop_front() {
    00886         __TBB_ASSERT( !empty(), "attempt to pop item from empty task_list" );
    00887         task* result = first;
    00888         first = result->prefix().next;
    00889         if( !first ) next_ptr = &first;
    00890         return *result;
    00891     }
    00892
    00894     void clear() {
    00895         first=NULL;
    00896         next_ptr=&first;
    00897     }
    00898 };
    00899
    00900 inline void interface5::internal::task_base::spawn( task& t ) {
    00901     t.prefix().owner->spawn( t, t.prefix().next );
    00902 }
    00903
    00904 inline void interface5::internal::task_base::spawn( task_list& list ) {
    00905     if( task* t = list.first ) {
    00906         t->prefix().owner->spawn( *t, *list.next_ptr );
    00907         list.clear();
    00908     }
    00909 }
    00910
    00911 inline void task::spawn_root_and_wait( task_list& root_list ) {
    00912     if( task* t = root_list.first ) {
    00913         t->prefix().owner->spawn_root_and_wait( *t, *root_list.next_ptr );
    00914         root_list.clear();
    00915     }
    00916 }
    00917
    00918 } // namespace tbb
    00919
    00920 inline void *operator new( size_t bytes, const tbb::internal::allocate_root_proxy& ) {
    00921     return &tbb::internal::allocate_root_proxy::allocate(bytes);
    00922 }
    00923
    00924 inline void operator delete( void* task, const tbb::internal::allocate_root_proxy& ) {
    00925     tbb::internal::allocate_root_proxy::free( *static_cast<tbb::task*>(task) );
    00926 }
    00927
    00928 #if __TBB_TASK_GROUP_CONTEXT
    00929 inline void *operator new( size_t bytes, const tbb::internal::allocate_root_with_context_proxy& p ) {
    00930     return &p.allocate(bytes);
    00931 }
    00932
    00933 inline void operator delete( void* task, const tbb::internal::allocate_root_with_context_proxy& p ) {
    00934     p.free( *static_cast<tbb::task*>(task) );
    00935 }
    00936 #endif /* __TBB_TASK_GROUP_CONTEXT */
    00937
    00938 inline void *operator new( size_t bytes, const tbb::internal::allocate_continuation_proxy& p ) {
    00939     return &p.allocate(bytes);
    00940 }
    00941
    00942 inline void operator delete( void* task, const tbb::internal::allocate_continuation_proxy& p ) {
    00943     p.free( *static_cast<tbb::task*>(task) );
    00944 }
    00945
    00946 inline void *operator new( size_t bytes, const tbb::internal::allocate_child_proxy& p ) {
    00947     return &p.allocate(bytes);
    00948 }
    00949
    00950 inline void operator delete( void* task, const tbb::internal::allocate_child_proxy& p ) {
    00951     p.free( *static_cast<tbb::task*>(task) );
    00952 }
    00953
    00954 inline void *operator new( size_t bytes, const tbb::internal::allocate_additional_child_of_proxy& p ) {
    00955     return &p.allocate(bytes);
    00956 }
    00957
    00958 inline void operator delete( void* task, const tbb::internal::allocate_additional_child_of_proxy& p ) {
    00959     p.free( *static_cast<tbb::task*>(task) );
    00960 }
    00961
    00962 #endif /* __TBB_task_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.