Monday, August 24, 2015

Changing scheduling priorities with priocntl(2)

The priocntl(2) and priocntlset(2) are the main APIs that allow programmatic access to scheduling parameters in Solaris or illumos. But they're a bit cumbersome to use, so here's a simple example of how to raise the user priority of a shell process with priocntl(2). Two things first:

(a) this raises the "user priority" of the current thread, where the actual priority of the thread is determined by other factors (which you may need to look at if the user priority isn't enough);

(b) shell processes start of in the IA or "interactive" class because they're spawned off of the X server, this example puts the thread in the TS or "time share" class which is the default scheduling class.
#include <stdlib.h>
#include <stdio.h>
#include <err.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/priocntl.h>
#include <sys/tspriocntl.h>

void
get_prio(void)
{
    pcinfo_t     pcinfo;
    pcparms_t    pcparms;
    tsparms_t    *tsparms;

    pcparms.pc_cid = PC_CLNULL;

    if (priocntl(P_LWPID, P_MYID, PC_GETPARMS, &pcparms) == -1) {
        perror("failed to get class id\n");
        return;
    }

    printf("class %d\n", pcparms.pc_cid);

    if (priocntl(P_LWPID, P_MYID, PC_GETPARMS, &pcparms) != -1) {
        tsparms = (tsparms_t *)pcparms.pc_clparms;
        printf("uprilim %d\n", tsparms->ts_uprilim);
        printf("pri %d\n", tsparms->ts_upri);
    } else {
        perror("failed to get prio\n");
    }
}

void
set_prio(void)
{
    pcinfo_t     pcinfo;
    pcparms_t    pcparms;
    tsparms_t    *tsparms;

    (void) strcpy(pcinfo.pc_clname, "TS");

    if (priocntl(P_LWPID, P_MYID, PC_GETCID, &pcinfo) != -1) {
        pcparms.pc_cid = pcinfo.pc_cid;

        tsparms = (tsparms_t *)pcparms.pc_clparms;
        tsparms->ts_uprilim = 10;
        tsparms->ts_upri = 10;
   
        if (priocntl(P_LWPID, P_MYID, PC_SETPARMS,
            &pcparms) == -1) {
            perror("failed to increase upri");
        }
    }
}

int
main(int argc, char **argv)
{
    get_prio();
    set_prio();
    get_prio();

    return (0);
}

No comments:

Post a Comment