Wimp_SendMessage
Lothar (3292) 134 posts |
I would need to share a common variable among two tasks A and B My first try was for task A to send a Message_RAMFetch to all tasks, and “divert” the buffer address field to pass the variable. This “works” since task B can take the variable through Wimp_Poll, and all other tasks ignore this “unexpected” Message_RAMFetch. But I still feel this is asking for later trouble, therefore I would welcome a better approach. To use a regular Wimp_TransferBlock for this seems difficult, since task B after start does not know task A handle yet. It would require task B to use TaskManager_EnumerateTasks and lots of TaskManager_TaskNameFromHandle. Or do I miss something? Passing the variable instead through the clipboard, or PipeFS, or a file, is slow. Best approach would possibly be to reserve a physical RAM word, to hold the common variable, and for task A and B to use OS_Memory to get logical pointers to that physical RAM word. I would try this next. But may result in other trouble. |
Chris Johns (8262) 242 posts |
Could you use a system variable? (OS_SetVarVal / OS_ReadVarVal)? |
Rick Murray (539) 13840 posts |
How much data? If you get yourself a MessageBlock allocation, you can use normal SendMessage calls to pass about 200 bytes. You can also use “broadcast” when the receiver task handle isn’t known, as only your apps will use your messages… |
Chris Hall (132) 3554 posts |
Yes using messages is the right approach (provided you don’t need to send more than about 200 bytes) – it can work both ways, task A can broadcast or send data and task B can send or broadcast a message asking for data from task A. SatNav broadcasts a message when it has a fix and this has the effect of starting up RiscOSM if it isn’t currently running and display a map of the location. They then send messages back and forth so you get a moving map display as you move around. All done with an allocated message block. See SatNav (which is written in BASIC) and its Help file. |
Dave Higton (1515) 3526 posts |
Lothar, what you want to do seems very similar to what I’ve done with a group of my applications which work together to implement my heating control system. Although the tasks start up in a defined order on power-up, of course any of the apps can be stopped and re-started, e.g. for test, maintenance and upgrade. This means that the tasks have to be capable of starting up in any order. When a task starts up, it searches for the task handle of each of the other apps it has to communicate with. This is done in a function that loops through calls to TaskManager_EnumerateTasks until either it finds the one it’s looking for (in which case it returns the handle), or it doesn’t (in which case it returns 0). Subsequently it listens for Message_TaskInitialise and Message_TaskCloseDown and checks these for tasks it needs to know of, updating the task handle appropriately. So each task knows the handles of each of its companion tasks at all times. It works a treat for me. You can define your own Wimp messages (and you can get official allocations if you wish to publish your apps). If the data you want to communicate will fit in the payload of a Wimp message, you can do it directly; otherwise it makes sense for the messages to initiate a RAM transfer. |
Bryan (8467) 468 posts |
I understand that replies are focusing on the sending of messages (as that is the title of the topic), but the OP does talk about a need to “share a variable between two tasks”
seems the simplest and least inefficient option for the problem. I suppose it all depends on how often the variable is updated. |
Lothar (3292) 134 posts |
Wimp_SendMessage now works well and easy enough for me. I now use “unexpected” Message_RAMTransmit instead of Message_RAMFetch for the broadcast to not break other tasks drag-to-save operations. It would be preferable though to have instead an “official” Message_Broadcast added to the message codes. This should broadcast the whole data(236) as is – so any task may have a look at it: https://www.riscosopen.org/wiki/documentation/show/Message%20Codes Should I put this into the Wish lists? Or is there other procedure? By the way the documentation is wrong: https://www.riscosopen.org/wiki/documentation/show/Message_RAMFetch The “competitor” has it correct: http://www.riscos.com/support/developers/prm/wimp.html > OS_SetVarVal / OS_ReadVarVal If I understand correctly this is not very safe, because another task could accidentally delete it. No protection. > OS_Memory I am still looking into this. This would be fastest. But may require a module. And I run into another problem, but will ask this separately: I thought the zero page is now protected against write from tasks? But still could write accidentally into a null pointer. No error. |