Changes between Version 6 and Version 7 of Old/Documentation/OTG/DebugNote


Ignore:
Timestamp:
Feb 17, 2006, 10:34:56 PM (18 years ago)
Author:
zhibinwu
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • Old/Documentation/OTG/DebugNote

    v6 v7  
    164164So, when it is set to fix rate, each packet will be transmit at this rate 11 times.
    165165             
     166
     167=== Wrapping Linux Threads in C++ classes ===
     168
     169Refer to Root software:
     170
     171esting the root TThread class, we  made some experiences
     172running a class member function as a (Linux-)pthread, which might help you.
     173
     174Since pthread_create (and also the TThread constructor) expects a C function to be run,
     175it needs the pointer to the class instance as function argument (4th argument of
     176pthread_create), if you want to run a member function of this C++ class.
     177When C++ methods are called from within a class, internally the class instance pointer
     178("this") is always passed as invisible first argument.
     179Thus  the "C" call of any C++ member function by pointer requires
     180the class object address as first argument...
     181
     182For example,
     183in root TThread class, the implementation for pthreads (THREAD_PosixThread.cxx)
     184starts the member function void* TThread::Fun (which calls your own function
     185passed to the TThread constructor) as pthread with the pointer to the TThread instance
     186TThread* th as argument:
     187{{{
     188int ierr = pthread_create(&id, attr, &TThread::Fun,th);
     189}}}
     190(in method TPosixThread::Run(TThread* th))
     191
     192Additionally, if you want to run a member void myfunction of any class Myclass as TThread,
     193you also have to pass the address to the class as function argument of TThread constructor,
     194since TThread::Fun uses a C function call to invoke your function:
     195{{{
     196 TThread* mythread= new TThread("My Thread",
     197         (void(*) (void *)) &Myclass::myfunction,
     198         (void*) &Myclass);
     199  mythread->Run();
     200}}}
     201when you create TThread from within class Myclass, you may write
     202{{{
     203TThread* mythread= new TThread("My Thread",
     204         (void(*) (void *)) &myfunction,
     205         (void*) this);
     206  mythread->Run();
     207}}}
     208The required cast of &myfunction produced a compiler warning in our tests
     209(egcs-2.91.66 Debian GNU/Linux (egcs-1.1.2 release)); however, the example
     210was compiled and runs.
     211
     212And
     213please don't mix a ptr-to-function and a ptr-to-member-function.
     214The former is just the address of a function. The later is
     215a structure containing
     216
     217   * the function address for non-virtual functions
     218   * the vtable index for virtual functions
     219   * the this pointer offset
     220
     221The representation of the structure is implementation specific,
     222and does for some compilers even depend on whether the class
     223has virtual functions or multiple inheritance or not.
     224
     225All this is needed to calculate
     226    *   the actual entry point address
     227    *   and the effective this pointer
     228when the ptr-to-member-function is finally used in a call.
     229In cases like multiple inherited base classes with virtual
     230functions in virtual base classes things get nontrivial here!
     231
     232Inspect the C++ lanuage definition for the allowed conversions
     233and casts of a ptr-to-member-function, and you'll see, there are
     234very few.
     235
     236In the light of all this I wonder portable Joern's code example is.
     237
     238Beyond that, the code
     239{{{
     240 TThread* mythread= new TThread("My Thread",
     241         (void(*) (void *)) &Myclass::myfunction,
     242         (void*) &Myclass);
     243}}}
     244will probably not give the desired result if Myclass uses
     245multiple inheritance and myfunction is from one of the base
     246classes (that's why the PTMF struct may contain a this offset).
     247
     248And
     249
     250Pthread standard allows only simple C function.
     251
     252TThread::Fun is static member of a class. A static member function == C function.
     253So it will work with all compilers/platforms.
     254I introduced static member function TThread::Fun and not simple C function
     255only do not pollute the name space.
     256
     257But you still can use nonstatic virtual member  function in Pthread.
     258
     259For example you want to call virtual finction void A::F()
     260By C++ rules you mas provide 2 pointers:
     261 A* p  - pointer to class instance
     262 void (A::*f)()  - pointer to function
     263
     264 Then you calculate pointer f = &A::F;
     265
     266User function for Pthread
     267{{{
     268user(void* adr)
     269{
     270  A inst;
     271  (A::*f)() = ((A::*)())adr;
     272  (inst.*f)();
     273}
     274}}}
     275In the example instance of A:: created inside of function.
     276But it is easy to pass this pointer via intermediate object
     277which keeps both poiners, to instance and to function.
     278Pointer to this object passed by adr uf user routine.
     279
     280So, there is no any limitation in THread::
     281
     282
     283
     284