Friday, 18 May 2018

Get the currently process priority & scheduling policy & priority, also change the priority

Get the currently process priority & scheduling policy & priority, also change the priority

API Description:

 #include <sched.h>
       int sched_get_priority_max(int policy);
       int sched_get_priority_min(int policy);
  • sched_get_priority_max() returns the maximum priority value that can be used with the scheduling algorithm identified by policy.
  • sched_get_priority_min() returns the minimum priority value that can be used with the scheduling algorithm identified by policy.

 #include <sched.h>

       int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param);
       int sched_getscheduler(pid_t pid);

  • The sched_setscheduler() system call sets both the scheduling policy and parameters for the thread whose ID is specified in pid.
  • If pid equals zero, the scheduling policy and parameters of the calling thread will be set.


#include <sys/time.h>
#include <sys/resource.h>
             int getpriority(int which, int who);
            int setpriority(int which, int who, int prio);
  • The scheduling priority of the process, process group, or user, as indicated by which and who is obtained with the getpriority() call and set with the setpriority() call.
  • The value which is one of PRIO_PROCESS, PRIO_PGRP, or PRIO_USER, and who is interpreted relative to which (a process identifier for PRIO_PROCESS, process group identifier for PRIO_PGRP, and a user ID for PRIO_USER).
  • A zero value for who denotes (respectively) the calling process, the process group of the calling process, or the real user ID of the calling process.

  • Prio is a value in the range -20 to 19 (but see the Notes below). The default priority is 0; lower priorities cause more favorable scheduling.

#include <sched.h>
      int sched_setparam(pid_t pid, const struct sched_param *param);
      int sched_getparam(pid_t pid, struct sched_param *param);

struct sched_param {
    ...
    int sched_priority;
    ...
};
  • sched_setparam() sets the scheduling parameters associated with the scheduling policy for the process identified by pid. If pid is zero, then the parameters of the calling process are set.


Program:


#include <stdio.h>
#include <sched.h>   // sched_getscheduler & set

/* For getpriority & setpriority */
#include <sys/time.h>
#include <sys/resource.h>

#include <errno.h>   // For errno
#include <stdlib.h>   // For exit
#include <string.h>  // for memset

const static int SCHED_POLICY_MAX = 3;
const char *sched_policies[] = {
    "SCHED_OTHER",
    "SCHED_FIFO",
    "SCHED_RR",
    "SCHED_BATCH"
};

int print_sched_type(pid_t pid)
{
    int policy = sched_getscheduler(pid);
    if (policy < 0) {
        perror("Syscall sched_getscheduler() had problems");
        return -1;
    }
    if (policy > SCHED_POLICY_MAX) {
        printf("Syscall sched_getscheduler() returned a policy number greater than allowed!\n");
        return -1;
    }
    printf("The current scheduling policy is: %s\n", sched_policies[policy]);
 
void print_process_prio(pid_t pid)
{
    /* Get the proirity of this process. This is the NON-REALTIME priority.
     *   http://linux.die.net/man/2/getpriority
     */
    /* This can return -1 as a legitimate value, so first clear errno
     * and make sure to check it after the call.
     */
    errno = 0;
    int this_prio = getpriority(PRIO_PROCESS, pid);

    if ((this_prio == -1) && (errno)) {
        perror("Syscall getpriority failed");
    } else {
        printf("Process priority is: %i\n", this_prio);
    }
}

void print_sched_priority(pid_t pid)
{
    /* Get and inspect the scheduling parameters.  This can contain realtime relevant
     * information if this process is operating with SCHED_FIFO
     */
    struct sched_param param;

    if (sched_getparam(pid, &param) < 0) {
        perror("Syscall sched_getparam barfed");
    } else {
        printf("The sched_param schedule priority is: %i\n", param.sched_priority);
    }
}

void hline(void)
{
    char str[82];
    memset(str, '-', 80);
    str[80] = '\n';
    str[81] = '\0';
    printf("%s", str);
}

int main(int argc, char *argv[])
{
    int policy = -1;

    /* Get the maximum schedule priority
http://linux.die.net/man/2/sched_get_priority_max
     */
    int max_prio_FIFO = sched_get_priority_max(SCHED_FIFO);
    int max_prio_RR = sched_get_priority_max(SCHED_RR);
    int max_prio_OTHER = sched_get_priority_max(SCHED_OTHER);

    printf("Scheduling Priority Maximums:\n"
            "    SCHED_FIFO: %i\n"
            "    SCHED_RR: %i\n"
            "    SCHED_OTHER: %i\n",
            max_prio_FIFO,
            max_prio_RR,
            max_prio_OTHER);

    /* Get the minimum schedule priorities for each process scheduling type
     *  http://linux.die.net/man/2/sched_get_priority_min
     */
    int min_prio_FIFO = sched_get_priority_min(SCHED_FIFO);
    int min_prio_RR = sched_get_priority_min(SCHED_RR);
    int min_prio_OTHER = sched_get_priority_min(SCHED_OTHER);
   printf("Scheduling Priority Minimums:\n"
            "    SCHED_FIFO: %i\n"
            "    SCHED_RR: %i\n"
            "    SCHED_OTHER: %i\n",
            min_prio_FIFO,
            min_prio_RR,
            min_prio_OTHER);

    print_process_prio(0);
    print_sched_priority(0);
    policy = print_sched_type(0);    // If we run on ubuntu getting default proces schedule is "Other"

    hline();


    /* Need to run from root user if we need to change the process priroty,
       otherwise it will thrown on error */
    printf("Attempting to switch process to SCHED_FIFO...\n");
    struct sched_param sp;
    memset(&sp, 0, sizeof(sp));
    sp.sched_priority = 50; /* This cannot be higher than max_prio_FIFO! */
    if (sched_setscheduler(0, SCHED_FIFO, &sp) < 0) {
        perror("Problem setting scheduling policy to SCHED_FIFO (probably need rtprio rule in /etc/security/limits.conf)");
        exit(1);
    }

    print_process_prio(0);
    print_sched_priority(0);
    print_sched_type(0);

    printf("\nTest completed successfully!\n");
}

Output without Root permission:

sample$ ./a.out
Scheduling Priority Maximums:
    SCHED_FIFO: 99
    SCHED_RR: 99
    SCHED_OTHER: 0
Scheduling Priority Minimums:
    SCHED_FIFO: 1
    SCHED_RR: 1
    SCHED_OTHER: 0
Process priority is: 0
The sched_param schedule priority is: 0
The current scheduling policy is: SCHED_OTHER
--------------------------------------------------------------------------------
Attempting to switch process to SCHED_FIFO...
Problem setting scheduling policy to SCHED_FIFO (probably need rtprio rule in /etc/security/limits.conf): Operation not permitted

Output with Root permission:

labuser@labuser-virtual-machine:~/velrajk/sample$ sudo ./a.out
[sudo] password for labuser:
Scheduling Priority Maximums:
    SCHED_FIFO: 99
    SCHED_RR: 99
    SCHED_OTHER: 0
Scheduling Priority Minimums:
    SCHED_FIFO: 1
    SCHED_RR: 1
    SCHED_OTHER: 0
Process priority is: 0
The sched_param schedule priority is: 0
The current scheduling policy is: SCHED_OTHER
--------------------------------------------------------------------------------
Attempting to switch process to SCHED_FIFO...
Process priority is: 0
The sched_param schedule priority is: 50
The current scheduling policy is: SCHED_FIFO

Test completed successfully!




No comments:

Post a Comment