Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
New Contributor I
25 Views

Understanding Internals of tbb::task

Hi,

I'm very confused as to what the reinterpret_casts within the allocation functions do. I don't see how you can get a pointer to the proxy from an instance of a tbb::task.

For example:

//! Returns proxy for overloaded new that allocates a child task of *this.
internal::allocate_child_proxy& allocate_child() {
return *reinterpret_cast<:ALLOCATE_CHILD_PROXY>(this);
}


Thanks,

AJ
0 Kudos
2 Replies
Highlighted
Black Belt
25 Views

There is no actual proxy object: the pointer to "this" is just (temporarily) disguised as another type, to select a specific "operator new" overload (at compile time). I'm not sure what to think of it, though...
0 Kudos
Highlighted
25 Views

> There is no actual proxy object: the pointer to "this" is just (temporarily) disguised as another type, to select a specific "operator new" overload (at compile time).
Not only that, but also the pointer to the current task is passed to the real allocation function via such a masquerade, and used there. See the following methods that complement allocate_child():
[cpp]// in task.h
inline void *operator new( size_t bytes, const tbb::internal::allocate_child_proxy& p ) {
    return &p.allocate(bytes);
}
// in task.cpp
task& allocate_child_proxy::allocate( size_t size ) const {
    task& t = *((task*)this);
    __TBB_ASSERT( AssertOkay(t), NULL );
    GenericScheduler* v = static_cast(t.prefix().owner);
    return v->allocate_task( size, __TBB_ALLOC_TASK_ARGS(&t, t.prefix().depth+1, t.prefix().context) );
}
[/cpp]

Considered that there now exists five different proxy objects and correspondingly five overloaded operators new, some kind of pointer casting seems inevitable in order to pass task pointer to each one. The implementation could differ however; e.g. we could use five different unions instead of reinterpret_cast.
0 Kudos