How to access globals variables of one task from another?

5 posts / 0 new
Last post
hypex
hypex's picture
Offline
Last seen: 3 months 3 weeks ago
Joined: 2011-09-09 16:20
How to access globals variables of one task from another?

Hi guys.

There's something I've been wondering. Is there some protocol in place for accessing global variables of another task in OS4 PPC code? Looking at examples code just accesses variables regardless.

In the 68K days we had things like geta4() type functions. Or just taking care of it yourself with a bit of ASM. But what about OS4?

I tend to be pedantic about these things and if I need pass data or modify it I tend to keep it inside an object that I send to another task. For example, in an interrupt, I would make use of the user data field to pass an object.

That's a rather low level example, but what about in general code? Say, a parent task having variables read by a child task? Or even, a library function that needs to run code, which belongs to a library master task?

This timer interrupt example below does pass a data pointer as user data. But it doesn't access it as a parameter. Nor does it use IExec as a parameter. But rather, it accesses each directly. Unless I'm missing something I didn't know this was a special feature of interrupt routines.

https://wiki.amigaos.net/wiki/Exec_Interrupts#Software_Interrupts

thomas
thomas's picture
Offline
Last seen: 3 months 1 week ago
Joined: 2011-05-16 14:23
Re: How to access globals variables of one task from another?

I tend to be pedantic about these things and if I need pass data or modify it I tend to keep it inside an object that I send to another task. For example, in an interrupt, I would make use of the user data field to pass an object.

That's the right way to handle it :)

That's a rather low level example, but what about in general code? Say, a parent task having variables read by a child task?

I usually implement a protocol similar to what Workbench does. I create the child with CreateNewProc. As first action the child WaitPort()s on its pr_MsgPort. The creator then sends an initialisation message to the child's pr_MsgPort.

Now it depends on what the child is used for. If the child is a server of some kind which should process additional messages, the creator waits on a reply for the intitial message and the child replies to the message once it has done its initialization.

If the child should do some asynchronous processing and then quit, the creator proceeds without waiting, the child does its work and replies to the message when it's done and quits. The parent knows that the child's work is done when it receives the reply.

If the shared memory block should be updated by multiple processes, I also include a struct SignalSemaphore and each task does an ObtainSemaphore before it accesses the data and ReleaseSemaphore afterwards.

Sharing interface pointers and library bases is another story. Normally this works by just referencing the global symbol. Often it is not possible to do it otherwise in C without a lot of programming efforts. However, it does not work with bsdsocket.library and other libraries which create a new base for each OpenLibrary call.

hypex
hypex's picture
Offline
Last seen: 3 months 3 weeks ago
Joined: 2011-09-09 16:20
Re: How to access globals variables of one task from another?

Thanks for your reply.

That's the right way to handle it :)

I'm on the right track then. :-)

I usually implement a protocol similar to what Workbench does. I create the child with CreateNewProc. As first action the child WaitPort()s on its pr_MsgPort. The creator then sends an initialisation message to the child's pr_MsgPort.

That makes sense.

Now it depends on what the child is used for. If the child is a server of some kind which should process additional messages, the creator waits on a reply for the intitial message and the child replies to the message once it has done its initialization.

Looks organised that way.

If the child should do some asynchronous processing and then quit, the creator proceeds without waiting, the child does its work and replies to the message when it's done and quits. The parent knows that the child's work is done when it receives the reply.

I wonder if that could be reduced to signals. Perhaps not since both would need to know what signal was used.

If the shared memory block should be updated by multiple processes, I also include a struct SignalSemaphore and each task does an ObtainSemaphore before it accesses the data and ReleaseSemaphore afterwards.

I do that myself. Usually when writing library code that could be called from multiple processes. I semaphore lock an object that only my library function knows about.

Sharing interface pointers and library bases is another story. Normally this works by just referencing the global symbol. Often it is not possible to do it otherwise in C without a lot of programming efforts. However, it does not work with bsdsocket.library and other libraries which create a new base for each OpenLibrary call.

I'm currently looking at 68K library code I intend to port to PPC. The different ABI and places for parameters looks like the hardest to manage.

Though it's a known about, the different bsdsocket.library bases does cause grief for some people. Amiga E does that in the library mode. Which has caused me trouble with code that doesn't expect it. In Amiga terms dynamic library bases are not thread safe. :-)

thomas
thomas's picture
Offline
Last seen: 3 months 1 week ago
Joined: 2011-05-16 14:23
Re: How to access globals variables of one task from another?

I wonder if that could be reduced to signals.

Normally you would want to get a result from the task. For example if you want to decode picture files asynchronously, you'd create the task, send it a file name and when it is finished you'd receive a pointer to a bitmap.

hypex
hypex's picture
Offline
Last seen: 3 months 3 weeks ago
Joined: 2011-09-09 16:20
Re: How to access globals variables of one task from another?

There isn't too much info on this floating about. Unless it's hidden in the SDK. But apparently the default on OS4 is to compile for a large data model. So we don't need to worry about global pointers and can access them whenever we like. Unless we are using small data model.

Log in or register to post comments