sched_setscheduler(2)

Bruce Dawson (VPN) jbd at codemeta.com
Thu Nov 8 16:16:06 EST 2012


The (rather severely hacked) code is attached - I'm using a netbook with 
cygwin right now and can't seem to do a cut&paste from the window.

It was built with cc latencytest.c -o latencytest

The executable was SetUID and owned by root. I also tried sudo'ing it.

Output:

    jbd at beaglebone:~$ ./latencytest
    ./latencytest starting...
    My original scheduling policy is SCHED_OTHER (0)
    The original minimum scheduling priority is 0, the maximum is 0
    sched_get_priority_max(1) returned 99
    sched_get_priority_min(1) returned 1
    My target scheduling policy is SCHED_FIFO (1)
    The target minimum scheduling priority is 1, the maximum is 99
    params.sched_priority now set to 98
    sched_setscheduler (0, SCHED_FIFO (1), ...) failed: Operation not
    permitted
    My scheduling policy is SCHED_OTHER
    The minimum scheduling priority is 0, the maximum is 0

I also put the following in /etc/security/limits.d/99realtime.conf:

    @jbd - rtprio 99
    @jbd - memlock unlimited

Note that I don't have the mlock code in the above example - I wanted to 
get this working first.

--Bruce

On 11/8/2012 3:17 PM, Kevin D. Clark wrote:
> Bruce Dawson writes:
>
>> Does anyone have any experience with this system call?
> Can you give us some code with your exact setup for
> sched_setscheduler()?
>
> Using this call requires a bit of setup ; there are a quite a few
> things that could go wrong or not be setup correctly, etc.  Being able
> to look at a snippet of your code would be very helpful.
>
> Also, could you run the snippet of code on your target machine and
> provide us with the strace output?
>
> Kind regards,
>
> --kevin

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.gnhlug.org/mailman/private/gnhlug-discuss/attachments/20121108/dc77d20b/attachment.html 
-------------- next part --------------
/**
   latencytest.c - Measures how long it takes to get a character echoed
     back from a XBee (which should be on /dev/ttyS0).

     FYI: This needs to run as super-user because it uses the scheduling
     calls and locks itself in memory to reduce latency.

   $Header$
**/

static char * _version_ = "$Id$";

#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
#include <linux/sched.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>

const char * PolicyToStr (int policy) {
  static char buf[BUFSIZ];
  switch (policy) {
  case SCHED_OTHER:
    snprintf(buf, sizeof(buf), "SCHED_OTHER (%d)", policy);
    break;
  case SCHED_IDLE:
    snprintf(buf, sizeof(buf), "SCHED_IDLE (%d)", policy);
    break;
  case SCHED_BATCH:
    snprintf(buf, sizeof(buf), "SCHED_BATCH (%d)", policy);
    break;
  case SCHED_FIFO:
    snprintf(buf, sizeof(buf), "SCHED_FIFO (%d)", policy);
    break;
  case SCHED_RR:
    snprintf(buf, sizeof(buf), "SCHED_RR (%d)", policy);
    break;
  default:
    snprintf(buf, sizeof(buf), "Unknown!: %d", policy);
    break;
  }
  return buf;
}

main(int argc, char ** argv) {
  int origpolicy;			/* Current process' scheduling
				   priority */
  int origPolicyMaxPriority;	/* Maximum priority for the original
				   policy */
  int origPolicyMinPriority;	/* Minimum priority for the original
				   policy */
  int tempPolicyMaxPriority;	/* Maximum priority for the wanted
				   policy */
  int tempPolicyMinPriority;	/* Minimum priority for the wanted
				   policy */
  pid_t pid;			/* My Process ID */
  int temppolicy = SCHED_FIFO;	/* Set to First-In scheduling */
  struct sched_param params; /* Scheduling parameters */
  int retval;			/* Return value from function calls */

  printf("%s starting...\n", argv[0]);
  pid = 0;			/* Use this process' ID */
  
  /* Get original max and min priorities. */
  if ((origpolicy = sched_getscheduler((pid_t) 0)) < 0) {
    perror("sched_getscheduler(0) failed");
  };
  if ((origPolicyMaxPriority = sched_get_priority_max(origpolicy)) < 0) {
    fprintf(stderr, "sched_get_priority_max(%d) failed: %s", origpolicy,
	    strerror(errno));
  };
  if ((origPolicyMinPriority = sched_get_priority_min(origpolicy)) < 0) {
    fprintf(stderr, "sched_get_priority_min(%d) failed", origpolicy,
	    strerror(errno));
  };
  printf("My original scheduling policy is %s\n", PolicyToStr(origpolicy));
  printf ("The original minimum scheduling priority is %d, the maximum is %d\n",
	  origPolicyMinPriority, origPolicyMaxPriority);

  /* Get max and min priorities of wanted scheduling policy. */
  if ((tempPolicyMaxPriority = sched_get_priority_max(temppolicy)) < 0) {
    fprintf(stderr, "sched_get_priority_max(%d) failed: %s\n", temppolicy,
	    strerror(errno));
  } else {
    fprintf (stderr, "sched_get_priority_max(%d) returned %d\n",
	     temppolicy, tempPolicyMaxPriority);
  }
  if ((tempPolicyMinPriority = sched_get_priority_min(temppolicy)) < 0) {
    fprintf(stderr, "sched_get_priority_min(%d) failed: %s\n", temppolicy,
	    strerror(errno));
  } else {
    fprintf (stderr, "sched_get_priority_min(%d) returned %d\n",
	     temppolicy, tempPolicyMinPriority);
  }
  printf("My target scheduling policy is %s\n", PolicyToStr(temppolicy));
  printf ("The target minimum scheduling priority is %d, the maximum is %d\n",
	  tempPolicyMinPriority, tempPolicyMaxPriority);

  /* Get scheduling parameters. */
  retval = sched_getparam (pid, &params);
  if (retval < 0) {
    fprintf (stderr, "sched_getparam(%d,...) failed: %s\nQuiting...\n",
	     pid, strerror(errno));
    /* Can't continue if we can't get scheduling parameters! */
    exit(-1);
  } else {
    /* Alter the priority in this scheduling policy. */
    if (tempPolicyMaxPriority == tempPolicyMinPriority) {
      params.sched_priority = tempPolicyMaxPriority;
    } else {
      params.sched_priority = tempPolicyMaxPriority - 1;
    }
    printf ("params.sched_priority now set to %d\n", params.sched_priority);
  }

  /* Set scheduler. After this call everything executes at ultra-high
     priority and nothing else on the system will run. */
  retval = sched_setscheduler (pid, temppolicy, &params);
  if (retval < 0) {
    fprintf(stderr, "sched_setscheduler (%d, %d, ...) failed: %s\n",
	    pid, temppolicy, strerror(errno));
  } 
  if (retval != 0) {
    fprintf (stderr, "sched_setscheduler (%d, %d, ...) returned unexpected value: %d\nContinuing...\n", pid, temppolicy, retval);
  } else {
    printf ("It worked - now running in high-priority mode\n");

    /* Alter the priority in this scheduling policy. */
    if (tempPolicyMaxPriority == tempPolicyMinPriority) {
      params.sched_priority = tempPolicyMaxPriority;
    } else {
      params.sched_priority = tempPolicyMaxPriority - 1;
    }
    fprintf (stderr, "params.sched_priority now set to %d\n",
	     params.sched_priority);
  

    /* Do things in ultra-high-priority mode. */
    /* ... */

    /* Return to normal priority. */
    retval = sched_setscheduler (pid, origpolicy, &params);
    if (retval < 0) {
      fprintf(stderr, "sched_setscheduler (%d, %d, ...) failed: %s\nQuiting.\n",
	      pid, origpolicy, strerror(errno));
      exit(-1);
    } else {
      fprintf(stderr, "Now running at original scheduler policy\n");
    }
  }

  if ((origpolicy = sched_getscheduler((pid_t) 0)) < 0) {
    perror("sched_getscheduler(0) failed");
  };
  printf("My scheduling policy is ");
  switch (origpolicy) {
    case SCHED_OTHER:
      printf("SCHED_OTHER");
      break;
    case SCHED_IDLE:
      printf("SCHED_IDLE");
      break;
    case SCHED_BATCH:
      printf("SCHED_BATCH");
      break;
    case SCHED_FIFO:
      printf("SCHED_FIFO");
      break;
    case SCHED_RR:
      printf("SCHED_RR");
      break;
    default:
      printf("Unknown!: %d", origpolicy);
      break;
    }
  printf ("\n");

  if ((origPolicyMaxPriority = sched_get_priority_max(origpolicy)) < 0) {
    fprintf(stderr, "sched_get_priority_max(%d) failed: %s", origpolicy,
	    strerror(errno));
  };
  if ((origPolicyMinPriority = sched_get_priority_min(origpolicy)) < 0) {
    fprintf(stderr, "sched_get_priority_min(%d) failed", origpolicy,
	    strerror(errno));
  };
  printf ("The minimum scheduling priority is %d, the maximum is %d\n",
	  origPolicyMinPriority, origPolicyMaxPriority);
}

/**
   $Log$
**/


More information about the gnhlug-discuss mailing list