[pok-devel] [45] Correct the scheduler when changing thread and partition at the same time |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/pok-devel Archives
]
Revision: 45
Author: jrosen
Date: 2013-02-01 11:48:59 +0100 (Fri, 01 Feb 2013)
Log Message:
-----------
Correct the scheduler when changing thread and partition at the same time
the scheduler would first switch partition then switch task.
this meant that when switching task, the old task (of the old partition) would
have its context saved as the old task of the new partition.
This would work correctly if the old task was the idle task because it can run in any partition,
which is why this problem was undetected for so long
Modified Paths:
--------------
trunk/kernel/core/debug.c
trunk/kernel/core/partition.c
trunk/kernel/core/sched.c
trunk/kernel/include/core/partition.h
trunk/kernel/include/core/sched.h
Modified: trunk/kernel/core/debug.c
===================================================================
--- trunk/kernel/core/debug.c 2013-01-25 12:28:02 UTC (rev 44)
+++ trunk/kernel/core/debug.c 2013-02-01 10:48:59 UTC (rev 45)
@@ -54,7 +54,7 @@
printf ("Base vaddr : 0x%x\n", POK_CURRENT_PARTITION.base_vaddr);
printf ("Size : %d\n", POK_CURRENT_PARTITION.size);
printf ("Current thread : %d\n", POK_CURRENT_PARTITION.current_thread);
- printf ("Prev current thread : %d\n", POK_CURRENT_PARTITION.prev_current_thread);
+ printf ("Prev current thread : %d\n", POK_CURRENT_PARTITION.prev_thread);
printf ("Main thread : %d\n", POK_CURRENT_PARTITION.thread_main);
printf ("Main thread entry : 0x%x\n", POK_CURRENT_PARTITION.thread_main_entry);
printf ("Partition threads sp :");
Modified: trunk/kernel/core/partition.c
===================================================================
--- trunk/kernel/core/partition.c 2013-01-25 12:28:02 UTC (rev 44)
+++ trunk/kernel/core/partition.c 2013-02-01 10:48:59 UTC (rev 45)
@@ -97,7 +97,7 @@
pok_partitions[pid].thread_index = 0;
pok_partitions[pid].current_thread = pok_partitions[pid].thread_index_low;
- pok_partitions[pid].prev_current_thread = IDLE_THREAD;
+ pok_partitions[pid].prev_thread = IDLE_THREAD; // breaks the rule of prev_thread not being idle, but it's just for init
#ifdef POK_NEEDS_ERROR_HANDLING
pok_partitions[pid].thread_error = 0;
@@ -200,7 +200,7 @@
pok_partitions[i].thread_index = 0;
pok_partitions[i].thread_main = 0;
pok_partitions[i].current_thread = IDLE_THREAD;
- pok_partitions[i].prev_current_thread = IDLE_THREAD;
+ pok_partitions[i].prev_thread = IDLE_THREAD; // breaks the rule of prev_thread not being idle, but it's just for init
#ifdef POK_NEEDS_SCHED_HFPPS
pok_partitions[i].payback = 0;
@@ -241,6 +241,7 @@
#endif
pok_partition_setup_main_thread (i);
+ pok_partitions[i].current_thread = pok_partitions[i].thread_main;
}
return POK_ERRNO_OK;
Modified: trunk/kernel/core/sched.c
===================================================================
--- trunk/kernel/core/sched.c 2013-01-25 12:28:02 UTC (rev 44)
+++ trunk/kernel/core/sched.c 2013-02-01 10:48:59 UTC (rev 45)
@@ -65,7 +65,6 @@
uint8_t pok_sched_slots_allocation[POK_CONFIG_SCHEDULING_NBSLOTS]
= (uint8_t[]) POK_CONFIG_SCHEDULING_SLOTS_ALLOCATION;
-uint32_t prev_current_thread;
pok_sched_t pok_global_sched;
uint64_t pok_sched_next_deadline;
uint64_t pok_sched_next_major_frame;
@@ -129,8 +128,9 @@
}
#ifdef POK_NEEDS_PARTITIONS
-pok_partition_t* pok_elect_partition()
+uint8_t pok_elect_partition()
{
+ uint8_t next_partition = POK_SCHED_CURRENT_PARTITION;
# if POK_CONFIG_NB_PARTITIONS > 1
uint64_t now = POK_GETTICK();
@@ -151,39 +151,33 @@
* FIXME : current debug session about exceptions-handled
printf ("Switch from partition %d to partition %d\n", pok_current_partition, pok_sched_current_slot);
printf ("old current thread = %d\n", POK_SCHED_CURRENT_THREAD);
- printf ("old prev current thread = %d\n", prev_current_thread);
printf ("new current thread = %d\n", pok_partitions[pok_sched_current_slot].current_thread);
- printf ("new prev current thread = %d\n", pok_partitions[pok_sched_current_slot].prev_current_thread);
+ printf ("new prev current thread = %d\n", pok_partitions[pok_sched_current_slot].prev_thread);
*/
- pok_partitions[pok_current_partition].prev_current_thread = prev_current_thread;
- pok_partitions[pok_current_partition].current_thread = POK_SCHED_CURRENT_THREAD;
+ next_partition = pok_sched_slots_allocation[pok_sched_current_slot];
- pok_current_partition = pok_sched_slots_allocation[pok_sched_current_slot];
-
- prev_current_thread = pok_partitions[pok_current_partition].prev_current_thread;
- current_thread = pok_partitions[pok_current_partition].current_thread;
-
#ifdef POK_NEEDS_SCHED_HFPPS
- if (pok_partitions[pok_current_partition].payback > 0) // pay back!
+ if (pok_partitions[next_partition].payback > 0) // pay back!
{
// new deadline
- pok_sched_next_deadline -= pok_partitions[pok_current_partition].payback;
- pok_partitions[pok_current_partition].payback = 0;
+ pok_sched_next_deadline -= pok_partitions[next_partition].payback;
+ pok_partitions[next_partition].payback = 0;
}
#endif /* POK_NEEDS_SCHED_HFPPS */
}
# endif /* POK_CONFIG_NB_PARTITIONS > 1 */
- return (&(pok_partitions[pok_current_partition]));
+ return next_partition;
}
#endif /* POK_NEEDS_PARTITIONS */
#ifdef POK_NEEDS_PARTITIONS
-uint32_t pok_elect_thread(pok_partition_t* current_partition)
+uint32_t pok_elect_thread(uint8_t new_partition_id)
{
uint64_t now = POK_GETTICK();
+ pok_partition_t* new_partition = &(pok_partitions[new_partition_id]);
/*
@@ -194,9 +188,9 @@
* type
*/
pok_thread_t* thread;
- for (i = 0; i < pok_partitions[pok_current_partition].nthreads; i++)
+ for (i = 0; i < new_partition->nthreads; i++)
{
- thread = &(pok_threads[current_partition->thread_index_low + i]);
+ thread = &(pok_threads[new_partition->thread_index_low + i]);
#if defined (POK_NEEDS_LOCKOBJECTS) || defined (POK_NEEDS_PORTS_QUEUEING) || defined (POK_NEEDS_PORTS_SAMPLING)
if ((thread->state == POK_STATE_WAITING) && (thread->wakeup_time <= now))
@@ -217,32 +211,31 @@
* We elect the thread to be executed.
*/
uint32_t elected;
- switch (current_partition->mode)
+ switch (new_partition->mode)
{
case POK_PARTITION_MODE_INIT_COLD:
case POK_PARTITION_MODE_INIT_WARM:
#ifdef POK_NEEDS_ERROR_HANDLING
- if ((current_partition->thread_error != 0) &&
- (pok_threads[current_partition->thread_error].state != POK_STATE_STOPPED))
+ if ((new_partition->thread_error != 0) &&
+ (pok_threads[new_partition->thread_error].state != POK_STATE_STOPPED))
{
- elected = current_partition->thread_error;
+ elected = new_partition->thread_error;
}
else
{
- elected = current_partition->thread_main;
+ elected = new_partition->thread_main;
}
#endif
- elected = current_partition->thread_main;
+ elected = new_partition->thread_main;
break;
case POK_PARTITION_MODE_NORMAL:
#ifdef POK_NEEDS_ERROR_HANDLING
- if ((POK_SCHED_CURRENT_THREAD == POK_CURRENT_PARTITION.thread_error) &&
- (POK_CURRENT_THREAD.state == POK_STATE_RUNNABLE))
+ if ((new_partition->current_thread == new_partition->thread_error) &&
+ (pok_threads[new_partition->current_thread].state == POK_STATE_RUNNABLE))
{
- elected = POK_CURRENT_PARTITION.thread_error;
- POK_CURRENT_PARTITION.current_thread = elected;
+ elected = new_partition->thread_error;
break;
}
#endif
@@ -262,15 +255,16 @@
POK_CURRENT_THREAD.state = POK_STATE_WAIT_NEXT_ACTIVATION;
}
}
- elected = POK_CURRENT_PARTITION.sched_func (current_partition->thread_index_low,
- current_partition->thread_index_high);
+ elected = new_partition->sched_func (new_partition->thread_index_low,
+ new_partition->thread_index_high,
+ new_partition->prev_thread,
+ new_partition->current_thread);
#ifdef POK_NEEDS_INSTRUMENTATION
- if ( (elected != IDLE_THREAD) && (elected != POK_CURRENT_PARTITION.thread_main))
+ if ( (elected != IDLE_THREAD) && (elected != new_partition->thread_main))
{
pok_instrumentation_running_task (elected);
}
#endif
- POK_CURRENT_PARTITION.current_thread = elected;
break;
@@ -298,6 +292,7 @@
void pok_sched()
{
uint32_t elected_thread = 0;
+ uint8_t elected_partition = POK_SCHED_CURRENT_PARTITION;
#ifdef POK_NEEDS_SCHED_HFPPS
uint64_t now = POK_GETTICK();
@@ -315,10 +310,18 @@
else /* overmegadirty */
#endif /* POK_NEEDS_SCHED_HFPPS */
{
- pok_partition_t* elected_partition = pok_elect_partition();
+
+ elected_partition = pok_elect_partition();
elected_thread = pok_elect_thread(elected_partition);
}
+ pok_current_partition = elected_partition;
+ if(pok_partitions[pok_current_partition].current_thread != elected_thread) {
+ if(pok_partitions[pok_current_partition].current_thread != IDLE_THREAD) {
+ pok_partitions[pok_current_partition].prev_thread = pok_partitions[pok_current_partition].current_thread;
+ }
+ pok_partitions[pok_current_partition].current_thread = elected_thread;
+ }
pok_sched_context_switch(elected_thread);
}
#else
@@ -360,6 +363,7 @@
{
return;
}
+
current_sp = &POK_CURRENT_THREAD.sp;
new_sp = pok_threads[elected_id].sp;
/*
@@ -376,26 +380,14 @@
}
#ifdef POK_NEEDS_SCHED_RMS
-uint32_t pok_sched_part_rms (const uint32_t index_low, const uint32_t index_high)
+uint32_t pok_sched_part_rms (const uint32_t index_low, const uint32_t index_high,const uint32_t __attribute__((unused)) prev_thread,const uint32_t __attribute__((unused)) current_thread)
{
uint32_t res;
#ifdef POK_NEEDS_DEBUG
uint32_t from;
+ from = prev_thread;
#endif
- if (POK_SCHED_CURRENT_THREAD == IDLE_THREAD)
- {
- res = prev_current_thread;
- }
- else
- {
- res = POK_SCHED_CURRENT_THREAD;
- }
-
-#ifdef POK_NEEDS_DEBUG
- from = res;
-#endif
-
res= index_low;
do
@@ -412,10 +404,6 @@
if ((res == index_low) && (pok_threads[res].state != POK_STATE_RUNNABLE))
{
res = IDLE_THREAD;
- if (POK_SCHED_CURRENT_THREAD != IDLE_THREAD)
- {
- prev_current_thread = POK_SCHED_CURRENT_THREAD;
- }
}
#ifdef POK_NEEDS_DEBUG
@@ -441,25 +429,25 @@
#endif /* POK_NEEDS_SCHED_RMS */
-uint32_t pok_sched_part_rr (const uint32_t index_low, const uint32_t index_high)
+uint32_t pok_sched_part_rr (const uint32_t index_low, const uint32_t index_high,const uint32_t prev_thread,const uint32_t current_thread)
{
uint32_t res;
uint32_t from;
- if (POK_SCHED_CURRENT_THREAD == IDLE_THREAD)
+ if (current_thread == IDLE_THREAD)
{
- res = prev_current_thread;
+ res = prev_thread;
}
else
{
- res = POK_SCHED_CURRENT_THREAD;
+ res = current_thread;
}
from = res;
- if ((POK_CURRENT_THREAD.remaining_time_capacity > 0) && (POK_CURRENT_THREAD.state == POK_STATE_RUNNABLE))
+ if ((pok_threads[current_thread].remaining_time_capacity > 0) && (pok_threads[current_thread].state == POK_STATE_RUNNABLE))
{
- return POK_SCHED_CURRENT_THREAD;
+ return current_thread;
}
do
@@ -475,10 +463,6 @@
if ((res == from) && (pok_threads[res].state != POK_STATE_RUNNABLE))
{
res = IDLE_THREAD;
- if (POK_SCHED_CURRENT_THREAD != IDLE_THREAD)
- {
- prev_current_thread = POK_SCHED_CURRENT_THREAD;
- }
}
return res;
}
Modified: trunk/kernel/include/core/partition.h
===================================================================
--- trunk/kernel/include/core/partition.h 2013-01-25 12:28:02 UTC (rev 44)
+++ trunk/kernel/include/core/partition.h 2013-02-01 10:48:59 UTC (rev 45)
@@ -82,10 +82,10 @@
pok_sched_t sched; /**< The associated for the partition to schedule its threads */
- uint32_t (*sched_func)(uint32_t low, uint32_t high); /**< Scheduling function to scheduler threads */
+ uint32_t (*sched_func)(uint32_t low, uint32_t high,uint32_t prev_thread, uint32_t cur_thread); /**< Scheduling function to scheduler threads */
uint64_t activation; /**< Last activation time of the partition */
- uint32_t prev_current_thread; /**< member for the scheduler (previous scheduled thread inside the partition */
+ uint32_t prev_thread; /**< member for the scheduler (previous scheduled real thread inside the partition,i.e not the idle thread */
uint32_t current_thread; /**< member for the scheduler (current executed thread inside the partition */
uint32_t thread_index_low; /**< The low index in the threads table */
Modified: trunk/kernel/include/core/sched.h
===================================================================
--- trunk/kernel/include/core/sched.h 2013-01-25 12:28:02 UTC (rev 44)
+++ trunk/kernel/include/core/sched.h 2013-02-01 10:48:59 UTC (rev 45)
@@ -54,8 +54,8 @@
/* Scheduler election method */
uint8_t pok_sched_election (void);
-uint32_t pok_sched_part_rr (const uint32_t ,const uint32_t);
-uint32_t pok_sched_part_rms (const uint32_t ,const uint32_t);
+uint32_t pok_sched_part_rr (const uint32_t ,const uint32_t,const uint32_t prev_thread,const uint32_t current_thread);
+uint32_t pok_sched_part_rms (const uint32_t ,const uint32_t,const uint32_t prev_thread,const uint32_t current_thread);
/* Context switch functions */
void pok_sched_context_switch (const uint32_t);