SCHED_RR preempted by SCHED_OTHER

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi all,
We work on powerpc board with kernel 2.6.29.6-rt23.
The kernel is configured with  "Complete Preemption (Real-Time)".
Working on our software, we have a strange behavior.
A real time thread (SCHED_RR) can be preempted by non real time one (SCHED_OTHER).

We wrote a little test program (at the end of  this mail).
This program creates 2 threads, a SCHED_RR one which processes during about 12s (long for a real time, but just for test), and a SCHED_OTHER one, started after the first one, which just modifies a global variable. The second one should not run during the execution of
the first one. But it appends, the global variable is modified.

> rr_other
Create thread
OTHER ran during RR
The end
>

Is it normal, a non real time thread preempts a real time one ? (we think, it is not) Or is there something wrong in the test program, the kernel configuration, ... ?

PS: We have the same behavior with SCHED_FIFO.
We tried the same test program on a kernel without the rt patch, it seesms to work well.

Thanks

Denis

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sched.h>
#include <sys/mman.h>
#include <pthread.h>

#define MAX_SAFE_STACK    (8*1024) /* The maximum stack size which is
                   guaranteed safe to access without faulting */

pthread_t pthid_rr, pthid_other;
volatile int global_var = 0, global_modified = 0;

void stack_prefault(void)
{
   unsigned char dummy[MAX_SAFE_STACK];

   memset(&dummy, 0, MAX_SAFE_STACK);
   return;
}

void* thr_rr(void * arg)
{
   int i, j, local_var;

   sleep(2);    /* Let main continue */
   local_var = global_var;
   /* Processing for ~ 12s */
   for (j = 0; j < 120 ; j++) {
       for (i = 0; i < 5000000; i++); /* ~ 100ms on our powerpc */
   }
   if (global_var != local_var) {
       global_modified = 1;
   }
   pthread_exit(NULL);
}

void* thr_other(void * arg)
{
   int    i;

   sleep(4);    /* Start after RR thread */
   /* Loop 6 s */
   for (i = 0; i < 6; i++) {
       global_var = i;
       sleep(1);
   }
   pthread_exit(NULL);
}

void create_th(void)
{
   pthread_attr_t thread_attr_id;
   int status;
   struct sched_param schedparam;

   /* SCHED_RR thread */
   if ((status = pthread_attr_init(&thread_attr_id)) != 0) {
fprintf(stderr, "Error pthread_attr_init() for periodic: 0x%x\n", status);
       exit(-1);
   }
if ((status = pthread_attr_setschedpolicy(&thread_attr_id, SCHED_RR)) != 0) { fprintf(stderr, "Error pthread_attr_setschedpolicy() for periodic: 0x%x\n", status);
       exit(-1);
   }
if ((status = pthread_attr_setinheritsched(&thread_attr_id, PTHREAD_EXPLICIT_SCHED)) != 0) { fprintf(stderr, "Error pthread_attr_setinheritsched() for periodic: 0x%x\n", status);
       exit(-1);
   }
   schedparam.sched_priority = 60;
if ((status = pthread_attr_setschedparam(&thread_attr_id, &schedparam)) != 0) { fprintf(stderr, "Error pthread_attr_setschedparam() for periodic: 0x%x\n", status);
       exit(-1);
   }
if ((status = pthread_create(&pthid_rr, &thread_attr_id, thr_rr, (void *) 0)) != 0) { fprintf(stderr, "Error pthread_create() for periodic: 0x%x\n", status);
       exit(-1);
   }
   if ((status = pthread_attr_destroy(&thread_attr_id)) != 0) {
fprintf(stderr, "Error pthread_attr_destroy() for periodic: 0x%x\n", status);
       exit(-1);
   }
   /* SCHED_OTHER thread */
   if ((status = pthread_attr_init(&thread_attr_id)) != 0) {
fprintf(stderr, "Error pthread_attr_init() for other: 0x%x\n", status);
       exit(-1);
   }
if ((status = pthread_attr_setschedpolicy(&thread_attr_id, SCHED_OTHER)) != 0) { fprintf(stderr, "Error pthread_attr_setschedpolicy() for other: 0x%x\n", status);
       exit(-1);
   }
if ((status = pthread_attr_setinheritsched(&thread_attr_id, PTHREAD_EXPLICIT_SCHED)) != 0) { fprintf(stderr, "Error pthread_attr_setinheritsched() for other: 0x%x\n", status);
       exit(-1);
   }
if ((status = pthread_create(&pthid_other, &thread_attr_id, thr_other, (void *) 0)) != 0) {
       fprintf(stderr, "Error pthread_create() for other: 0x%x\n", status);
       exit(-1);
   }
   if ((status = pthread_attr_destroy(&thread_attr_id)) != 0) {
fprintf(stderr, "Error pthread_attr_destroy() for other: 0x%x\n", status);
       exit(-1);
   }
}

int main(int argc, char* argv[])
{
   /* Lock memory */
   if (mlockall(MCL_CURRENT|MCL_FUTURE) == -1) {
           perror("mlockall failed");
           exit(-2);
   }
   /* Pre-fault our stack */
   stack_prefault();

printf("Create thread\n"); create_th();
   /* Wait end of thread_other */
   if (pthread_join(pthid_other, NULL) != 0) {
       fprintf(stderr, "Error pthread_join() for periodic\n");
       exit(-1);
   }
   /* Wait end of thread_rr */
   if (pthread_join(pthid_rr, NULL) != 0) {
       fprintf(stderr, "Error pthread_join() for periodic\n");
       exit(-1);
   }
   if (global_modified) {
       printf("OTHER ran during RR\n");
   }
   printf("The end\n");
}

--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [RT Stable]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]

  Powered by Linux