[ In my last mail I did not put xenomai-help in CC, corrected by this. ] On Sat, Mar 17, 2012 at 11:52 PM, Ronny Meeus <[email protected]> wrote: > On Sat, Mar 17, 2012 at 11:42 AM, Philippe Gerum <[email protected]> wrote: >> On 03/08/2012 03:30 PM, Ronny Meeus wrote: >>> >>> Hello >>> >>> I'm are using the xenomai-forge pSOS skin (Mercury). >>> My application is running on a P4040 (Freescale PPC with 4 cores). >>> Some code snippets are put in this mail but the complete testcode is >>> also attached. >>> >>> I have a test task that just consumes the CPU: >>> >>> int run_test = 1; >>> static void perform_work(u_long counter,u_long b,u_long c,u_long d) >>> { >>> int i; >>> while (run_test) { >>> for (i=0;i<100000;i++); >>> (*(unsigned long*)counter)++; >>> } >>> while (1) tm_wkafter(1000); >>> } >>> >>> If I create 2 instances of this task with the T_SLICE option set: >>> >>> t_create("WORK",10,0,0,0,&tid); >>> t_start(tid,T_TSLICE, perform_work, args); >>> >>> >>> I see that only 1 task is consuming CPU. >>> >>> # taskset 1 ./roundrobin.exe& >>> # 0"000.543| [main] SCHED_RT priorities => [1 .. 99] >>> 0"000.656| [main] SCHED_RT.99 reserved for IRQ emulation >>> 0"000.692| [main] SCHED_RT.98 reserved for scheduler-lock emulation >>> 0 -> 6602 >>> 1 -> 0 >>> >>> If I adapt the code so that I call in my init the threadobj_start_rr >>> function, I see that the load is equally distributed over the 2 >>> threads: >>> >>> # taskset 1 ./roundrobin.exe& >>> # 0"000.557| [main] SCHED_RT priorities => [1 .. 99] >>> 0"000.672| [main] SCHED_RT.99 reserved for IRQ emulation >>> 0"000.708| [main] SCHED_RT.98 reserved for scheduler-lock emulation >>> 0 -> 3290 >>> 1 -> 3291 >>> >>> Here are the questions: >>> - why is the threadobj_start_rr function not called from the context >>> of the init of the psos layer. >> >> >> Because threadobj_start_rr() was originally designed to activate round-robin >> for all threads (some RTOS like VxWorks expose that kind of API), not on a >> per-thread basis. This is not what pSOS wants. >> >> The round-robin API is in state of flux for mercury, only the cobalt one is >> stable. This is why RR is not yet activated despite T_SLICE is recognized. >> >> >>> - why is the roundrobin implemented in this way? If the tasks would be >>> mapped on the SCHED_RR instead of the SCHED_FF the Linux scheduler >>> would take care of this. >> >> >> Nope. We need per-thread RR intervals, to manage multiple priority groups >> concurrently, and we also want to define that interval as we see fit for >> proper RTOS emulation. POSIX does not define anything like >> sched_set_rr_interval(), and the linux kernel applies a default fixed >> interval to all threads from the SCHED_RR class (100ms IIRC). >> >> So we have to emulate SCHED_RR over SCHED_FIFO plus a per-thread virtual >> timer. >> > > OK I understand. > >> >>> On the other hand, once the threadobj_start_rr function is called from >>> my init, and I create the tasks in T_NOTSLICE mode, the time-slicing >>> is still done. >> >> >> Because you called threadobj_start_rr(). >> > > Yes, indeed I called threadobj_start_rr to install the virtual timer > and to attach the signal handler, but the tasks are not running in > time-sliced mode. This means that the flag THREADOBJ_ROUNDROBIN is not > set within the thread object so I do not understand why I still see > the timeslicing being applied. > It looks to me that once the timer fires and the signal handler is > called, there is a context switch made anyhow. >
I was studying the code in more detail this time and I observed something which is strange to me. In the function threadobj_start_rr, both the round-robin virtual timer mechanism is installed and also the round-robin flag is set for all tasks currently existing in the system (This is what I missed before). Also from that moment on, all new tasks are running on round-robin mode, independent of the flags specified during the task creation. The only exception to this is that when a task calls t_mode to disable round-robin, in this case the round-robin is disabled. So for me this is not completely consistent and certainly not to what the user expects. I did a change and introduced a new function: threadobj_start_global_rr The patch is attached to the mail. I basically have split the installation of the signal handler and the activation of the round-robin mode for all tasks into 2 parts. The original function threadobj_start_rr just installs the signal handler and starts the timer with the interval that the user has specified. The newly introduced function (threadobj_start_global_rr) marks all tasks as round-robin active and all future tasks will also be marked. By splitting the logic of this function it is possible to work in a mode where the tasks itself (based on the flags given during task-creation or via t_mode) decides on the mode in which it wants to run or the application can decide that the round-robin will be activated globally (by calling threadobj_start_global_rr once during init for example). In the latter case the round-robin activation because global for all threads in the application process. I tested the change in my version and it looks like it behaves like it should be. Thanks --- Ronny
global_rr.patch
Description: Binary data
_______________________________________________ Xenomai-help mailing list [email protected] https://mail.gna.org/listinfo/xenomai-help
