Using File Manager From MP Tasks
Volume Number: 14
Issue Number: 8
Column Tag: Toolbox Techniques
Using the File Manager from MP Tasks
by by Matthew Xavier Mora
Edited by Peter N Lewis
How to get data in and out of your MP Task
One of the most common complaints I received while supporting MP Library in
Developer Technical Support was that you could not call the toolbox from an MP Task.
Multiple preemptive tasks are not much use if you cannot get data into and out of them
efficiently. This article shows one way to get data into and out of an MP Task using the
file manager, however the techniques used here can be modified for other I/O
operations (like audio, video or networking). "But, I thought you couldn't call the file
manager from MP Tasks?" Well, you thought wrong. :-) Read on...
In the early version of the MP library there was no easy way to call the toolbox
because the MP Library was designed to be compatible with Copland's kernel tasking
model. Since the Mac OS toolbox wasn't going to be available from Copland's kernel
tasks, the same was done for the Mac OS version of the MP Library. After the Copland
project was canceled it was decided to publish a few previously undocumented routines
that let you work with the Mac OS toolbox from a task. One of the routines published is
MPRPC. MPRPC is a remote procedure mechanism that lets you specify a routine to
execute at a time when it is safe to make toolbox calls. It does this by suspending the
task and then executing the supplied routine during SystemTask() time. The task is
suspended until MPYield is called or until any toolbox routine calls SystemTask().
MPRPC is used internally in the MP Library to implement calls such as MPAllocate
and MPAllocateSys (which is why these are blocking calls).
The code in this article is based on the MP File Library that I wrote before the MPRPC
call was published. The MP File Library used MPQueues to communicate with the main
task and have it execute toolbox commands.
Review
Let's review some of the MP programming guidelines and how adding blocking calls can
change some of these guidelines.
1. Your tasks should do a considerable amount of work. If not, the benefits of
using MP will be lost in the overhead of the scheduler and task switching.
Adding blocking calls to your tasks adds additional overhead. The main benefit
here is that by being able to call the toolbox from an MP Task your task can
run autonomously from the main application thread. This results in a better
user interface response from the application since the application can off load
a time consuming task and call the main event loop more often giving the
blocking calls more time to execute the toolbox calls.
2. You should allocate no more than (MPProcessors() - 1) number of tasks.
While it is important to keep the number of tasks low so that task switching
does not impact performance, adding blocking calls to a task will also hurt
performance if nothing calls MPYield(). "Wait, I thought MP Tasks were
preemptive?" Yes they are but if the task is blocked waiting on a resource, the
resource can't be released until the main thread calls WaitNextEvent() or
another task calls MPYield(). That being the case, if you use MPRPC calls it is
a good idea to bend the n-1 rule and create an extra task that can help unblock
any waiting tasks.
3. You should use MPQueues or MPSemaphores when communicating with
MP Tasks. This does not change if you are using MPRPC so you should heed this
warning.
Get On With It
OK, so how do I call the File Manager? For this simple example I will implement five
MP calls that duplicate FSpOpenDF, FSClose, FSRead, FSWrite and SetFPos. Those are