task.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_task_H
00022 #define __TBB_task_H
00023 
00024 #include "tbb_stddef.h"
00025 #include "tbb_machine.h"
00026 #include <climits>
00027 
00028 typedef struct ___itt_caller *__itt_caller;
00029 
00030 namespace tbb {
00031 
00032 class task;
00033 class task_list;
00034 
00035 #if __TBB_TASK_GROUP_CONTEXT
00036 class task_group_context;
00037 #endif /* __TBB_TASK_GROUP_CONTEXT */
00038 
00039 // MSVC does not allow taking the address of a member that was defined 
00040 // privately in task_base and made public in class task via a using declaration.
00041 #if _MSC_VER || (__GNUC__==3 && __GNUC_MINOR__<3)
00042 #define __TBB_TASK_BASE_ACCESS public
00043 #else
00044 #define __TBB_TASK_BASE_ACCESS private
00045 #endif
00046 
00047 namespace internal {
00048 
00049     class allocate_additional_child_of_proxy: no_assign {
00051         task* self;
00052         task& parent;
00053     public:
00054         explicit allocate_additional_child_of_proxy( task& parent_ ) : self(NULL), parent(parent_) {}
00055         task& __TBB_EXPORTED_METHOD allocate( size_t size ) const;
00056         void __TBB_EXPORTED_METHOD free( task& ) const;
00057     };
00058 
00059 }
00060 
00061 namespace interface5 {
00062     namespace internal {
00064 
00069         class task_base: tbb::internal::no_copy {
00070         __TBB_TASK_BASE_ACCESS:
00071             friend class tbb::task;
00072 
00074             static void spawn( task& t );
00075  
00077             static void spawn( task_list& list );
00078 
00080 
00082             static tbb::internal::allocate_additional_child_of_proxy allocate_additional_child_of( task& t ) {
00083                 return tbb::internal::allocate_additional_child_of_proxy(t);
00084             }
00085 
00087 
00091             static void __TBB_EXPORTED_FUNC destroy( task& victim );
00092         }; 
00093     } // internal
00094 } // interface5
00095 
00097 namespace internal {
00098 
00099     class scheduler: no_copy {
00100     public:
00102         virtual void spawn( task& first, task*& next ) = 0;
00103 
00105         virtual void wait_for_all( task& parent, task* child ) = 0;
00106 
00108         virtual void spawn_root_and_wait( task& first, task*& next ) = 0;
00109 
00111         //  Have to have it just to shut up overzealous compilation warnings
00112         virtual ~scheduler() = 0;
00113 
00115         virtual void enqueue( task& t, void* reserved ) = 0;
00116     };
00117 
00119 
00120     typedef intptr_t reference_count;
00121 
00123     typedef unsigned short affinity_id;
00124 
00125 #if __TBB_TASK_GROUP_CONTEXT
00126     class generic_scheduler;
00127 
00128     struct context_list_node_t {
00129         context_list_node_t *my_prev,
00130                             *my_next;
00131     };
00132 
00133     class allocate_root_with_context_proxy: no_assign {
00134         task_group_context& my_context;
00135     public:
00136         allocate_root_with_context_proxy ( task_group_context& ctx ) : my_context(ctx) {}
00137         task& __TBB_EXPORTED_METHOD allocate( size_t size ) const;
00138         void __TBB_EXPORTED_METHOD free( task& ) const;
00139     };
00140 #endif /* __TBB_TASK_GROUP_CONTEXT */
00141 
00142     class allocate_root_proxy: no_assign {
00143     public:
00144         static task& __TBB_EXPORTED_FUNC allocate( size_t size );
00145         static void __TBB_EXPORTED_FUNC free( task& );
00146     };
00147 
00148     class allocate_continuation_proxy: no_assign {
00149     public:
00150         task& __TBB_EXPORTED_METHOD allocate( size_t size ) const;
00151         void __TBB_EXPORTED_METHOD free( task& ) const;
00152     };
00153 
00154     class allocate_child_proxy: no_assign {
00155     public:
00156         task& __TBB_EXPORTED_METHOD allocate( size_t size ) const;
00157         void __TBB_EXPORTED_METHOD free( task& ) const;
00158     };
00159 
00161 
00166     class task_prefix {
00167     private:
00168         friend class tbb::task;
00169         friend class tbb::interface5::internal::task_base;
00170         friend class tbb::task_list;
00171         friend class internal::scheduler;
00172         friend class internal::allocate_root_proxy;
00173         friend class internal::allocate_child_proxy;
00174         friend class internal::allocate_continuation_proxy;
00175         friend class internal::allocate_additional_child_of_proxy;
00176 
00177 #if __TBB_TASK_GROUP_CONTEXT
00179 
00182         task_group_context  *context;
00183 #endif /* __TBB_TASK_GROUP_CONTEXT */
00184         
00186 
00191         scheduler* origin;
00192 
00193 #if TBB_PREVIEW_TASK_PRIORITY
00194         union {
00195 #endif /* TBB_PREVIEW_TASK_PRIORITY */
00197 
00199         scheduler* owner;
00200 
00201 #if TBB_PREVIEW_TASK_PRIORITY
00203 
00204         task* next_offloaded;
00205         };
00206 #endif /* TBB_PREVIEW_TASK_PRIORITY */
00207 
00209 
00212         tbb::task* parent;
00213 
00215 
00219         reference_count ref_count;
00220 
00222 
00224         int depth;
00225 
00227 
00228         unsigned char state;
00229 
00231 
00236         unsigned char extra_state;
00237 
00238         affinity_id affinity;
00239 
00241         tbb::task* next;
00242 
00244         tbb::task& task() {return *reinterpret_cast<tbb::task*>(this+1);}
00245     };
00246 
00247 } // namespace internal
00249 
00250 #if __TBB_TASK_GROUP_CONTEXT
00251 
00252 #if TBB_PREVIEW_TASK_PRIORITY
00253 namespace internal {
00254     static const int priority_stride_v4 = INT_MAX / 4;
00255 }
00256 
00257 enum priority_t {
00258     priority_normal = internal::priority_stride_v4 * 2,
00259     priority_low = priority_normal - internal::priority_stride_v4,
00260     priority_high = priority_normal + internal::priority_stride_v4
00261 };
00262 
00263 #endif /* TBB_PREVIEW_TASK_PRIORITY */
00264 
00265 #if TBB_USE_CAPTURED_EXCEPTION
00266     class tbb_exception;
00267 #else
00268     namespace internal {
00269         class tbb_exception_ptr;
00270     }
00271 #endif /* !TBB_USE_CAPTURED_EXCEPTION */
00272 
00273 class task_scheduler_init;
00274 
00276 
00296 class task_group_context : internal::no_copy {
00297 private:
00298     friend class internal::generic_scheduler;
00299     friend class task_scheduler_init;
00300 
00301 #if TBB_USE_CAPTURED_EXCEPTION
00302     typedef tbb_exception exception_container_type;
00303 #else
00304     typedef internal::tbb_exception_ptr exception_container_type;
00305 #endif
00306 
00307     enum version_traits_word_layout {
00308         traits_offset = 16,
00309         version_mask = 0xFFFF,
00310         traits_mask = 0xFFFFul << traits_offset
00311     };
00312 
00313 public:
00314     enum kind_type {
00315         isolated,
00316         bound
00317     };
00318 
00319     enum traits_type {
00320         exact_exception = 0x0001ul << traits_offset,
00321         concurrent_wait = 0x0004ul << traits_offset,
00322 #if TBB_USE_CAPTURED_EXCEPTION
00323         default_traits = 0
00324 #else
00325         default_traits = exact_exception
00326 #endif /* !TBB_USE_CAPTURED_EXCEPTION */
00327     };
00328 
00329 private:
00330     enum state {
00331         may_have_children = 1
00332     };
00333 
00334     union {
00336         kind_type my_kind;
00337         uintptr_t _my_kind_aligner;
00338     };
00339 
00341     task_group_context *my_parent;
00342 
00344 
00346     internal::context_list_node_t my_node;
00347 
00349     __itt_caller itt_caller;
00350 
00352 
00355     char _leading_padding[internal::NFS_MaxLineSize
00356                           - 2 * sizeof(uintptr_t)- sizeof(void*) - sizeof(internal::context_list_node_t)
00357                           - sizeof(__itt_caller)];
00358     
00360     uintptr_t my_cancellation_requested;
00361     
00363 
00366     uintptr_t  my_version_and_traits;
00367 
00369     exception_container_type *my_exception;
00370 
00372     internal::generic_scheduler *my_owner;
00373 
00375     uintptr_t my_state;
00376 
00377 #if TBB_PREVIEW_TASK_PRIORITY
00379     intptr_t my_priority;
00380 #endif /* TBB_PREVIEW_TASK_PRIORITY */
00381 
00383 
00384     char _trailing_padding[internal::NFS_MaxLineSize - 2 * sizeof(uintptr_t) - 2 * sizeof(void*)
00385 #if TBB_PREVIEW_TASK_PRIORITY
00386                             - sizeof(intptr_t)
00387 #endif /* TBB_PREVIEW_TASK_PRIORITY */
00388                           ];
00389 
00390 public:
00392 
00420     task_group_context ( kind_type relation_with_parent = bound,
00421                          uintptr_t traits = default_traits )
00422         : my_kind(relation_with_parent)
00423         , my_version_and_traits(1 | traits)
00424     {
00425         init();
00426     }
00427 
00428     __TBB_EXPORTED_METHOD ~task_group_context ();
00429 
00431 
00438     void __TBB_EXPORTED_METHOD reset ();
00439 
00441 
00448     bool __TBB_EXPORTED_METHOD cancel_group_execution ();
00449 
00451     bool __TBB_EXPORTED_METHOD is_group_execution_cancelled () const;
00452 
00454 
00460     void __TBB_EXPORTED_METHOD register_pending_exception ();
00461 
00462 #if TBB_PREVIEW_TASK_PRIORITY
00464     void set_priority ( priority_t );
00465 
00467     priority_t priority () const;
00468 #endif /* TBB_PREVIEW_TASK_PRIORITY */
00469 
00470 protected:
00472 
00473     void __TBB_EXPORTED_METHOD init ();
00474 
00475 private:
00476     friend class task;
00477     friend class internal::allocate_root_with_context_proxy;
00478 
00479     static const kind_type binding_required = bound;
00480     static const kind_type binding_completed = kind_type(bound+1);
00481     static const kind_type detached = kind_type(binding_completed+1);
00482     static const kind_type dying = kind_type(detached+1);
00483 
00485 
00487     template <typename T>
00488     void propagate_state_from_ancestors ( T task_group_context::*mptr_state, T new_state );
00489 
00491     inline void finish_initialization ( internal::generic_scheduler *local_sched );
00492 
00494     void bind_to ( internal::generic_scheduler *local_sched );
00495 
00497     void register_with ( internal::generic_scheduler *local_sched );
00498 
00499 }; // class task_group_context
00500 
00501 #endif /* __TBB_TASK_GROUP_CONTEXT */
00502 
00504 
00505 class task: __TBB_TASK_BASE_ACCESS interface5::internal::task_base {
00506 
00508     void __TBB_EXPORTED_METHOD internal_set_ref_count( int count );
00509 
00511     internal::reference_count __TBB_EXPORTED_METHOD internal_decrement_ref_count();
00512 
00513 protected:
00515     task() {prefix().extra_state=1;}
00516 
00517 public:
00519     virtual ~task() {}
00520 
00522     virtual task* execute() = 0;
00523 
00525     enum state_type {
00527         executing,
00529         reexecute,
00531         ready,
00533         allocated,
00535         freed,
00537         recycle 
00538     };
00539 
00540     //------------------------------------------------------------------------
00541     // Allocating tasks
00542     //------------------------------------------------------------------------
00543 
00545     static internal::allocate_root_proxy allocate_root() {
00546         return internal::allocate_root_proxy();
00547     }
00548 
00549 #if __TBB_TASK_GROUP_CONTEXT
00551     static internal::allocate_root_with_context_proxy allocate_root( task_group_context& ctx ) {
00552         return internal::allocate_root_with_context_proxy(ctx);
00553     }
00554 #endif /* __TBB_TASK_GROUP_CONTEXT */
00555 
00557 
00558     internal::allocate_continuation_proxy& allocate_continuation() {
00559         return *reinterpret_cast<internal::allocate_continuation_proxy*>(this);
00560     }
00561 
00563     internal::allocate_child_proxy& allocate_child() {
00564         return *reinterpret_cast<internal::allocate_child_proxy*>(this);
00565     }
00566 
00568     using task_base::allocate_additional_child_of;
00569 
00570 #if __TBB_DEPRECATED_TASK_INTERFACE
00572 
00576     void __TBB_EXPORTED_METHOD destroy( task& t );
00577 #else /* !__TBB_DEPRECATED_TASK_INTERFACE */
00579     using task_base::destroy;
00580 #endif /* !__TBB_DEPRECATED_TASK_INTERFACE */
00581 
00582     //------------------------------------------------------------------------
00583     // Recycling of tasks
00584     //------------------------------------------------------------------------
00585 
00587 
00593     void recycle_as_continuation() {
00594         __TBB_ASSERT( prefix().state==executing, "execute not running?" );
00595         prefix().state = allocated;
00596     }
00597 
00599 
00601     void recycle_as_safe_continuation() {
00602         __TBB_ASSERT( prefix().state==executing, "execute not running?" );
00603         prefix().state = recycle;
00604     }
00605 
00607     void recycle_as_child_of( task& new_parent ) {
00608         internal::task_prefix& p = prefix();
00609         __TBB_ASSERT( prefix().state==executing||prefix().state==allocated, "execute not running, or already recycled" );
00610         __TBB_ASSERT( prefix().ref_count==0, "no child tasks allowed when recycled as a child" );
00611         __TBB_ASSERT( p.parent==NULL, "parent must be null" );
00612         __TBB_ASSERT( new_parent.prefix().state<=recycle, "corrupt parent's state" );
00613         __TBB_ASSERT( new_parent.prefix().state!=freed, "parent already freed" );
00614         p.state = allocated;
00615         p.parent = &new_parent;
00616 #if __TBB_TASK_GROUP_CONTEXT
00617         p.context = new_parent.prefix().context;
00618 #endif /* __TBB_TASK_GROUP_CONTEXT */
00619     }
00620 
00622 
00623     void recycle_to_reexecute() {
00624         __TBB_ASSERT( prefix().state==executing, "execute not running, or already recycled" );
00625         __TBB_ASSERT( prefix().ref_count==0, "no child tasks allowed when recycled for reexecution" );
00626         prefix().state = reexecute;
00627     }
00628 
00629     // All depth-related methods are obsolete, and are retained for the sake 
00630     // of backward source compatibility only
00631     intptr_t depth() const {return 0;}
00632     void set_depth( intptr_t ) {}
00633     void add_to_depth( int ) {}
00634 
00635 
00636     //------------------------------------------------------------------------
00637     // Spawning and blocking
00638     //------------------------------------------------------------------------
00639 
00641     void set_ref_count( int count ) {
00642 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
00643         internal_set_ref_count(count);
00644 #else
00645         prefix().ref_count = count;
00646 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
00647     }
00648 
00650 
00651     void increment_ref_count() {
00652         __TBB_FetchAndIncrementWacquire( &prefix().ref_count );
00653     }
00654 
00656 
00657     int decrement_ref_count() {
00658 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
00659         return int(internal_decrement_ref_count());
00660 #else
00661         return int(__TBB_FetchAndDecrementWrelease( &prefix().ref_count ))-1;
00662 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
00663     }
00664 
00666     using task_base::spawn;
00667 
00669     void spawn_and_wait_for_all( task& child ) {
00670         prefix().owner->wait_for_all( *this, &child );
00671     }
00672 
00674     void __TBB_EXPORTED_METHOD spawn_and_wait_for_all( task_list& list );
00675 
00677     static void spawn_root_and_wait( task& root ) {
00678         root.prefix().owner->spawn_root_and_wait( root, root.prefix().next );
00679     }
00680 
00682 
00684     static void spawn_root_and_wait( task_list& root_list );
00685 
00687 
00688     void wait_for_all() {
00689         prefix().owner->wait_for_all( *this, NULL );
00690     }
00691 
00693 #if TBB_PREVIEW_TASK_PRIORITY
00694 
00704 #endif /* TBB_PREVIEW_TASK_PRIORITY */
00705     static void enqueue( task& t ) {
00706         t.prefix().owner->enqueue( t, NULL );
00707     }
00708 
00709 #if TBB_PREVIEW_TASK_PRIORITY
00711     static void enqueue( task& t, priority_t p ) {
00712         __TBB_ASSERT( p == priority_low || p == priority_normal || p == priority_high, "Invalid priority level value" );
00713         t.prefix().owner->enqueue( t, (void*)p );
00714     }
00715 #endif /* TBB_PREVIEW_TASK_PRIORITY */
00716 
00718     static task& __TBB_EXPORTED_FUNC self();
00719 
00721     task* parent() const {return prefix().parent;}
00722 
00723 #if __TBB_TASK_GROUP_CONTEXT
00725 
00726     task_group_context* context() {return prefix().context;}
00727 
00729     task_group_context* group () { return prefix().context; }
00730 #endif /* __TBB_TASK_GROUP_CONTEXT */   
00731 
00733     bool is_stolen_task() const {
00734         return (prefix().extra_state & 0x80)!=0;
00735     }
00736 
00737     //------------------------------------------------------------------------
00738     // Debugging
00739     //------------------------------------------------------------------------
00740 
00742     state_type state() const {return state_type(prefix().state);}
00743 
00745     int ref_count() const {
00746 #if TBB_USE_ASSERT
00747         internal::reference_count ref_count_ = prefix().ref_count;
00748         __TBB_ASSERT( ref_count_==int(ref_count_), "integer overflow error");
00749 #endif
00750         return int(prefix().ref_count);
00751     }
00752 
00754     bool __TBB_EXPORTED_METHOD is_owned_by_current_thread() const;
00755 
00756     //------------------------------------------------------------------------
00757     // Affinity
00758     //------------------------------------------------------------------------
00759  
00761 
00762     typedef internal::affinity_id affinity_id;
00763 
00765     void set_affinity( affinity_id id ) {prefix().affinity = id;}
00766 
00768     affinity_id affinity() const {return prefix().affinity;}
00769 
00771 
00775     virtual void __TBB_EXPORTED_METHOD note_affinity( affinity_id id );
00776 
00777 #if __TBB_TASK_GROUP_CONTEXT
00779 
00789     void __TBB_EXPORTED_METHOD change_group ( task_group_context& ctx );
00790 
00792 
00793     bool cancel_group_execution () { return prefix().context->cancel_group_execution(); }
00794 
00796     bool is_cancelled () const { return prefix().context->is_group_execution_cancelled(); }
00797 #endif /* __TBB_TASK_GROUP_CONTEXT */
00798 
00799 #if TBB_PREVIEW_TASK_PRIORITY
00801     void set_group_priority ( priority_t p ) {  prefix().context->set_priority(p); }
00802 
00804     priority_t group_priority () const { return prefix().context->priority(); }
00805 
00806 #endif /* TBB_PREVIEW_TASK_PRIORITY */
00807 
00808 private:
00809     friend class interface5::internal::task_base;
00810     friend class task_list;
00811     friend class internal::scheduler;
00812     friend class internal::allocate_root_proxy;
00813 #if __TBB_TASK_GROUP_CONTEXT
00814     friend class internal::allocate_root_with_context_proxy;
00815 #endif /* __TBB_TASK_GROUP_CONTEXT */
00816     friend class internal::allocate_continuation_proxy;
00817     friend class internal::allocate_child_proxy;
00818     friend class internal::allocate_additional_child_of_proxy;
00819     
00821 
00822     internal::task_prefix& prefix( internal::version_tag* = NULL ) const {
00823         return reinterpret_cast<internal::task_prefix*>(const_cast<task*>(this))[-1];
00824     }
00825 }; // class task
00826 
00828 
00829 class empty_task: public task {
00830     /*override*/ task* execute() {
00831         return NULL;
00832     }
00833 };
00834 
00836 
00838 class task_list: internal::no_copy {
00839 private:
00840     task* first;
00841     task** next_ptr;
00842     friend class task;
00843     friend class interface5::internal::task_base;
00844 public:
00846     task_list() : first(NULL), next_ptr(&first) {}
00847 
00849     ~task_list() {}
00850 
00852     bool empty() const {return !first;}
00853 
00855     void push_back( task& task ) {
00856         task.prefix().next = NULL;
00857         *next_ptr = &task;
00858         next_ptr = &task.prefix().next;
00859     }
00860 
00862     task& pop_front() {
00863         __TBB_ASSERT( !empty(), "attempt to pop item from empty task_list" );
00864         task* result = first;
00865         first = result->prefix().next;
00866         if( !first ) next_ptr = &first;
00867         return *result;
00868     }
00869 
00871     void clear() {
00872         first=NULL;
00873         next_ptr=&first;
00874     }
00875 };
00876 
00877 inline void interface5::internal::task_base::spawn( task& t ) {
00878     t.prefix().owner->spawn( t, t.prefix().next );
00879 }
00880 
00881 inline void interface5::internal::task_base::spawn( task_list& list ) {
00882     if( task* t = list.first ) {
00883         t->prefix().owner->spawn( *t, *list.next_ptr );
00884         list.clear();
00885     }
00886 }
00887 
00888 inline void task::spawn_root_and_wait( task_list& root_list ) {
00889     if( task* t = root_list.first ) {
00890         t->prefix().owner->spawn_root_and_wait( *t, *root_list.next_ptr );
00891         root_list.clear();
00892     }
00893 }
00894 
00895 } // namespace tbb
00896 
00897 inline void *operator new( size_t bytes, const tbb::internal::allocate_root_proxy& ) {
00898     return &tbb::internal::allocate_root_proxy::allocate(bytes);
00899 }
00900 
00901 inline void operator delete( void* task, const tbb::internal::allocate_root_proxy& ) {
00902     tbb::internal::allocate_root_proxy::free( *static_cast<tbb::task*>(task) );
00903 }
00904 
00905 #if __TBB_TASK_GROUP_CONTEXT
00906 inline void *operator new( size_t bytes, const tbb::internal::allocate_root_with_context_proxy& p ) {
00907     return &p.allocate(bytes);
00908 }
00909 
00910 inline void operator delete( void* task, const tbb::internal::allocate_root_with_context_proxy& p ) {
00911     p.free( *static_cast<tbb::task*>(task) );
00912 }
00913 #endif /* __TBB_TASK_GROUP_CONTEXT */
00914 
00915 inline void *operator new( size_t bytes, const tbb::internal::allocate_continuation_proxy& p ) {
00916     return &p.allocate(bytes);
00917 }
00918 
00919 inline void operator delete( void* task, const tbb::internal::allocate_continuation_proxy& p ) {
00920     p.free( *static_cast<tbb::task*>(task) );
00921 }
00922 
00923 inline void *operator new( size_t bytes, const tbb::internal::allocate_child_proxy& p ) {
00924     return &p.allocate(bytes);
00925 }
00926 
00927 inline void operator delete( void* task, const tbb::internal::allocate_child_proxy& p ) {
00928     p.free( *static_cast<tbb::task*>(task) );
00929 }
00930 
00931 inline void *operator new( size_t bytes, const tbb::internal::allocate_additional_child_of_proxy& p ) {
00932     return &p.allocate(bytes);
00933 }
00934 
00935 inline void operator delete( void* task, const tbb::internal::allocate_additional_child_of_proxy& p ) {
00936     p.free( *static_cast<tbb::task*>(task) );
00937 }
00938 
00939 #endif /* __TBB_task_H */

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.