Is there a way to basically call system()
, but with a predefined niceness value (20) and low IO priority from Objective-C?
(The low IO priority setting I'm talking about is the one launchd
has)
I'm trying to launch /usr/bin/purge
from within my Objective-C program.
It would also be ideal for the method to be approved for the Mac App Store.
Edit: Fork and exec no more, since OSX can't really fork
right. Single thread magic:
setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_THROTTLE);
system("nice -n 20 /usr/bin/purge");
setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_DEFAULT);
This can go anywhere, in a dispatch block if you want, or anywhere in your application. No fork
in sight. Also, feel free to replace system
with NSTask
if you want to stay ObjCish.
How about a good old fork
nexec
:
#include <unistd.h>
#include <sys/resource.h>
And:
if(fork()) {
/* Set IO priority */
setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_THROTTLE);
/*IO priority is inherited*/
execl("nice", "-n", "20", "/usr/bin/purge");
}
Let's walk through this:
fork
: Nothing to see heresetiopolicy_np
: This is the place where we set IO priority (like launchd). Here are the arguments:
IOPOL_TYPE_DISK
: We want to limit Disk I/O. There is no other option available anyway.IOPOL_SCOPE_PROCESS
: Affects this whole processIOPOL_THROTTLE
: This is the policy itself. Accouring to the Apple documentation, it specifies this: I/Os with THROTTLE policy are called THROTTLE I/Os. If a THROTTLE I/O request occurs within a small time window (usually a fraction of a second) of another NORMAL I/O request, the thread that issues the THROTTLE I/O is forced to sleep for a certain interval. This slows down the thread that issues the THROTTLE I/O so that NORMAL I/Os can utilize most of the disk I/O bandwidth. Furthermore, a NORMAL I/O request may bypass a previously issued THROTTLE I/O request in kernel or driver queues and be sent to the device first. In some circumstances, very large THROTTLE I/O requests will be broken into smaller requests which are then issued serially.
I/O priority is inherited, and the nice
part of the command sets the nice value.