I'm considering using C++ and Tornado for an upcoming project, however, I
am unsure as to how VxWorks handles C++ objects. Can an object's member
function (either virtual or non-virtual) be spawned as a task? And, if so,
does the member function then have all of the access privileges of a normal
member function? Are there any special considerations I should be aware of?
Thanks for any and all help. Examples or source code snippets would be
greatly appreciated.
Kris Kauper
C.S. Draper Laboratory
555 Technology Square, M/S 18
Cambridge, MA 02139
kka...@draper.com
617-258-1590
617-258-3858 (fax)
> I'm considering using C++ and Tornado for an upcoming project, however, I
> am unsure as to how VxWorks handles C++ objects. Can an object's member
> function (either virtual or non-virtual) be spawned as a task? And, if so,
> does the member function then have all of the access privileges of a normal
> member function? Are there any special considerations I should be aware of?
The safest and most portable way of calling a member function as the
entry point from a spawned task is to use a static member function
wrapper, passing an object pointer into this function which in turn
then calls the objects member function. Be careful: you must make
sure that the object's virtual function table has been set-up properly
if the member function you plan to call is virtual. One way of
synchronizing this is through a binary semaphore. The base class
would provide a static entry-point to vxWorks, and this function would
take an empty semaphore. The derived-most class constructor would
give the semaphore, and you're off.
For example:
class Task {
protected:
Task(char* name,
int priority=100,
int stackSize=0x5000,
bool floatingPoint=false) :
sync(ERROR),
id(ERROR)
{
sync = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY)
id = taskSpawn(
name,
priority,
floatingPoint ? VX_FP_TASK : 0,
stackSize,
static_cast<FUNCPTR>(entry),
static_cast<int>(this),
0, 0, 0, 0, 0, 0, 0, 0, 0);
}
virtual ~Task()
{
taskDelete(id);
}
void start()
{
semGive(sync);
}
virtual int main() = 0;
private:
static int entry(int arg)
{
Task& task = *static_cast<Task*>(arg);
semTake(task.sync, WAIT_FOREVER);
semDelete(task.sync);
return task.main();
}
SEM_ID sync;
int id;
};
class MyTask : public Task {
public:
MyTask() :
Task("myTask") {start();}
private:
int main()
{
// the main guts go here
return OK;
}
};
This is just a very rough sketch of one way you might solve the
problem. Of course, if it's possible for your MyTask object to be
deleted before the start() method has run and given the semaphore,
you'd want to clean that up in the destructor, but I doubt that's the
case.
--
-----------------------------------------------------------
Michael Carr Redstone Communications
*** Remove 'NOSPAM' from my email address when replying ***
For example: you want to spawn a task running member function called "Run" of
the object "MyObj", following the documentation, you would do:
VXWTask* pMyTask = new VXWTask("NewTask", MY_TASK_PRIORITY, 0,
MY_TASK_STACK_SIZE, (FUNCPTR)pMyObj->Run,
0,0,0,0,0,0,0,0,0,0);
where pMyObj is a pointer to MyObj
This will not work. You need to do this:
VXWTask* pMyTask = new VXWTask("NewTask", MY_TASK_PRIORITY, 0,
MY_TASK_STACK_SIZE, (FUNCPTR)pMyObj->Run,
(int)pMyObj,
0,0,0,0,0,0,0,0,0,0);
Van
Kris Kauper wrote:
> VxWorks
>
> I'm considering using C++ and Tornado for an upcoming project, however, I
> am unsure as to how VxWorks handles C++ objects. Can an object's member
> function (either virtual or non-virtual) be spawned as a task? And, if so,
> does the member function then have all of the access privileges of a normal
> member function? Are there any special considerations I should be aware of?
To my knowledge, only a static member function can be input to
taskSpawn, which precludes virtual members. To effect the behavior of
spawning a non-static member function (that is, one which 'knows' its
specific object identity), the object's 'this' pointer must be input as
an argument to taskSpawn, to be passed along to the threaded method.
Internally, that method will cast the argument back into the correct
object type, and thereby have access to the specific object state. It's
a bit awkward, but does work.
So for example, in the class definition:
class ActiveObject {
static int ThreadedMethod(void* objThis); // castable to FUNCPTR
int TID_; // the task id
...
};
The call to taskSpawn looks something like:
TID = taskSpawn( name_, priority_, options_, stackSize_,
(FUNCPTR)ThreadedMethod, // entry point
int(this), // arg1 to ThreadedMethod
... // add'l arguments
)
Inside of ThreadedMethod, cast the arg1 (int) back to its proper type:
ActiveObject::ThreadedMethod(void* objThis)
{
ActiveObject* This = (ActiveObject*)objThis;
... // now can operate on specific object, including calling member
fncs
}
> I'm considering using C++ and Tornado for an upcoming project, however, I
> am unsure as to how VxWorks handles C++ objects. Can an object's member
> function (either virtual or non-virtual) be spawned as a task? And, if so,
> does the member function then have all of the access privileges of a normal
> member function? Are there any special considerations I should be aware of?
> Thanks for any and all help. Examples or source code snippets would be
> greatly appreciated.
=================================
Jim Caprio
Moore Research Center, Inc.
(716)773-0333
FAX : (716)773-0462
email: cap...@research.moore.com
=================================
The taskSpawn() accept function entry_point as the parameter to spawn the
task. The function name has to be resolved when compiling and the function
has to be accessible when calling the taskSpawn().
In the C++, there are class object and the encoded function name for the
member function.
To integrate these two, I create C_API layer. The C_API layer, extern C
function, is used to wrap the member function and pass the C function name
into the taskSpawn(). You got to take care of object creation, i.e. either
from static class object or have the first C_API create the object for the
rest of the member functions.
This is the approach that I used for the projects on the Tornado, and it is
easy to implement. (This layer works as a bridge between C and C++, and
everything fit nicely together.)
HTH.
-Tom
email: s.w...@ieee.org