aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2009-09-05 15:31:27 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2009-09-05 15:31:27 +0000
commit7dfa36f86d896cdb824a9137a81f324c8243c4d9 (patch)
tree5b83e2db6919eaeaf8705830adea1939885b310a
parent3ee19d119a4a960a6bed887a1be775e7e7fd55cb (diff)
downloadChibiOS-7dfa36f86d896cdb824a9137a81f324c8243c4d9.tar.gz
ChibiOS-7dfa36f86d896cdb824a9137a81f324c8243c4d9.tar.bz2
ChibiOS-7dfa36f86d896cdb824a9137a81f324c8243c4d9.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1148 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r--os/kernel/include/scheduler.h24
-rw-r--r--os/kernel/include/threads.h3
-rw-r--r--os/kernel/src/chschd.c2
-rw-r--r--os/kernel/src/chthreads.c15
-rw-r--r--readme.txt2
-rw-r--r--test/testbmk.c120
6 files changed, 131 insertions, 35 deletions
diff --git a/os/kernel/include/scheduler.h b/os/kernel/include/scheduler.h
index 235761216..00294e190 100644
--- a/os/kernel/include/scheduler.h
+++ b/os/kernel/include/scheduler.h
@@ -78,6 +78,12 @@ typedef struct {
extern ReadyList rlist;
+#ifdef CH_CURRP_REGISTER_CACHE
+register Thread *currp asm(CH_CURRP_REGISTER_CACHE);
+#else
+#define currp rlist.r_current
+#endif
+
/*
* Scheduler APIs.
*/
@@ -96,11 +102,19 @@ extern "C" {
}
#endif
-#ifdef CH_CURRP_REGISTER_CACHE
-register Thread *currp asm(CH_CURRP_REGISTER_CACHE);
-#else
-#define currp rlist.r_current
-#endif
+/**
+ * @brief Determines if yielding is possible.
+ * @details This function returns @p TRUE if there is a ready thread with
+ * equal or higher priority.
+ */
+#define chSchCanYieldS() (firstprio(&rlist.r_queue) >= currp->p_prio)
+
+/**
+ * @brief Determines if the current thread must reschedule.
+ * @details This function returns @p TRUE if there is a ready thread with
+ * higher priority.
+ */
+#define chSchMustRescheduleS() (firstprio(&rlist.r_queue) >= currp->p_prio)
#endif /* _SCHEDULER_H_ */
diff --git a/os/kernel/include/threads.h b/os/kernel/include/threads.h
index 7155e9b32..da7dfc152 100644
--- a/os/kernel/include/threads.h
+++ b/os/kernel/include/threads.h
@@ -183,6 +183,9 @@ extern "C" {
#if CH_USE_WAITEXIT
msg_t chThdWait(Thread *tp);
#endif
+#if CH_USE_ROUNDROBIN
+ void chThdYield(void);
+#endif
#ifdef __cplusplus
}
#endif
diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c
index af24f5cf4..6183180bc 100644
--- a/os/kernel/src/chschd.c
+++ b/os/kernel/src/chschd.c
@@ -211,7 +211,7 @@ void chSchDoRescheduleI(void) {
void chSchRescheduleS(void) {
/* first thread in the runnable queue has higher priority than the running
* thread? */
- if (firstprio(&rlist.r_queue) > currp->p_prio)
+ if (chSchMustRescheduleS())
chSchDoRescheduleI();
}
diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c
index 583bc7c04..c18a4f8cd 100644
--- a/os/kernel/src/chthreads.c
+++ b/os/kernel/src/chthreads.c
@@ -290,6 +290,21 @@ void chThdSleepUntil(systime_t time) {
chSysUnlock();
}
+#if CH_USE_ROUNDROBIN
+/**
+ * @brief Yields the time slot.
+ * @details Yields the CPU control to the next thread in the ready list with
+ * equal priority, if any.
+ */
+void chThdYield(void) {
+
+ chSysLock();
+ if (chSchCanYieldS())
+ chSchDoRescheduleI();
+ chSysUnlock();
+}
+#endif /* CH_USE_ROUNDROBIN */
+
/**
* @brief Terminates the current thread by specifying an exit status code.
*
diff --git a/readme.txt b/readme.txt
index 8b0608363..8a90b6f15 100644
--- a/readme.txt
+++ b/readme.txt
@@ -12,6 +12,8 @@
- FIX: Fixed GCC 4.4.x related problems in CM3 port (bug 2846162).(backported
in stable branch)
- FIX: Fixed LPC214x UART problem (bug 2841088)(backported in stable branch).
+- NEW: Added new API chThdYield().
+- MEW: Added new benchmark about round robin rescheduling.
- NEW: Reorganized and rationalized the distribution tree and the
documentation.
- NEW: Enhanced serial driver. The driver now supports speed change at runtime
diff --git a/test/testbmk.c b/test/testbmk.c
index 7a99c37af..f44ae0b8b 100644
--- a/test/testbmk.c
+++ b/test/testbmk.c
@@ -418,7 +418,66 @@ const struct testcase testbmk7 = {
};
/**
- * @page test_benchmarks_008 I/O Queues throughput
+ * @page test_benchmarks_009 I/O Round-Robin voluntary rescedulation.
+ *
+ * <h2>Description</h2>
+ * Five threads are created at equal priority, each thread just increases a
+ * variable and yields.<br>
+ * The performance is calculated by measuring the number of iterations after
+ * a second of continuous operations.
+ */
+
+#if CH_USE_ROUNDROBIN
+static msg_t thread8(void *p) {
+
+ do {
+ chThdYield();
+ chThdYield();
+ chThdYield();
+ chThdYield();
+ (*(uint32_t *)p) += 4;
+ } while(!chThdShouldTerminate());
+ return 0;
+}
+
+static char *bmk8_gettest(void) {
+
+ return "Benchmark, round robin context switching";
+}
+
+static void bmk8_execute(void) {
+ uint32_t n;
+
+ n = 0;
+ test_wait_tick();
+
+ threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriority()-1, thread8, (void *)&n);
+ threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriority()-1, thread8, (void *)&n);
+ threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriority()-1, thread8, (void *)&n);
+ threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriority()-1, thread8, (void *)&n);
+ threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriority()-1, thread8, (void *)&n);
+
+ chThdSleepSeconds(1);
+ test_terminate_threads();
+ test_wait_threads();
+
+ test_print("--- Score : ");
+ test_printn(n);
+ test_print(" reschedulations/S, ");
+ test_printn(n);
+ test_println(" ctxswc/S");
+}
+
+const struct testcase testbmk8 = {
+ bmk8_gettest,
+ NULL,
+ NULL,
+ bmk8_execute
+};
+#endif
+
+/**
+ * @page test_benchmarks_009 I/O Queues throughput
*
* <h2>Description</h2>
* Four bytes are written and then read from an @p InputQueue into a continuous
@@ -427,12 +486,12 @@ const struct testcase testbmk7 = {
* a second of continuous operations.
*/
-static char *bmk8_gettest(void) {
+static char *bmk9_gettest(void) {
return "Benchmark, I/O Queues throughput";
}
-static void bmk8_execute(void) {
+static void bmk9_execute(void) {
static uint8_t ib[16];
static InputQueue iq;
@@ -459,15 +518,15 @@ static void bmk8_execute(void) {
test_println(" bytes/S");
}
-const struct testcase testbmk8 = {
- bmk8_gettest,
+const struct testcase testbmk9 = {
+ bmk9_gettest,
NULL,
NULL,
- bmk8_execute
+ bmk9_execute
};
/**
- * @page test_benchmarks_009 Virtual Timers set/reset performance
+ * @page test_benchmarks_010 Virtual Timers set/reset performance
*
* <h2>Description</h2>
* A virtual timer is set and immediately reset into a continuous loop.<br>
@@ -475,14 +534,14 @@ const struct testcase testbmk8 = {
* a second of continuous operations.
*/
-static char *bmk9_gettest(void) {
+static char *bmk10_gettest(void) {
return "Benchmark, virtual timers set/reset";
}
static void tmo(void *param) {}
-static void bmk9_execute(void) {
+static void bmk10_execute(void) {
static VirtualTimer vt1, vt2;
uint32_t n = 0;
@@ -505,15 +564,15 @@ static void bmk9_execute(void) {
test_println(" timers/S");
}
-const struct testcase testbmk9 = {
- bmk9_gettest,
+const struct testcase testbmk10 = {
+ bmk10_gettest,
NULL,
NULL,
- bmk9_execute
+ bmk10_execute
};
/**
- * @page test_benchmarks_010 Semaphores wait/signal performance
+ * @page test_benchmarks_011 Semaphores wait/signal performance
*
* <h2>Description</h2>
* A counting semaphore is taken/released into a continuous loop, no Context
@@ -522,17 +581,17 @@ const struct testcase testbmk9 = {
* a second of continuous operations.
*/
-static char *bmk10_gettest(void) {
+static char *bmk11_gettest(void) {
return "Benchmark, semaphores wait/signal";
}
-static void bmk10_setup(void) {
+static void bmk11_setup(void) {
chSemInit(&sem1, 1);
}
-static void bmk10_execute(void) {
+static void bmk11_execute(void) {
uint32_t n = 0;
test_wait_tick();
@@ -556,16 +615,16 @@ static void bmk10_execute(void) {
test_println(" wait+signal/S");
}
-const struct testcase testbmk10 = {
- bmk10_gettest,
- bmk10_setup,
+const struct testcase testbmk11 = {
+ bmk11_gettest,
+ bmk11_setup,
NULL,
- bmk10_execute
+ bmk11_execute
};
#if CH_USE_MUTEXES
/**
- * @page test_benchmarks_011 Mutexes lock/unlock performance
+ * @page test_benchmarks_012 Mutexes lock/unlock performance
*
* <h2>Description</h2>
* A mutex is locked/unlocked into a continuous loop, no Context Switch happens
@@ -574,17 +633,17 @@ const struct testcase testbmk10 = {
* a second of continuous operations.
*/
-static char *bmk11_gettest(void) {
+static char *bmk12_gettest(void) {
return "Benchmark, mutexes lock/unlock";
}
-static void bmk11_setup(void) {
+static void bmk12_setup(void) {
chMtxInit(&mtx1);
}
-static void bmk11_execute(void) {
+static void bmk12_execute(void) {
uint32_t n = 0;
test_wait_tick();
@@ -608,11 +667,11 @@ static void bmk11_execute(void) {
test_println(" lock+unlock/S");
}
-const struct testcase testbmk11 = {
- bmk11_gettest,
- bmk11_setup,
+const struct testcase testbmk12 = {
+ bmk12_gettest,
+ bmk12_setup,
NULL,
- bmk11_execute
+ bmk12_execute
};
#endif
@@ -628,11 +687,14 @@ const struct testcase * const patternbmk[] = {
&testbmk5,
&testbmk6,
&testbmk7,
+#if CH_USE_ROUNDROBIN
&testbmk8,
+#endif
&testbmk9,
&testbmk10,
-#if CH_USE_MUTEXES
&testbmk11,
+#if CH_USE_MUTEXES
+ &testbmk12,
#endif
#endif
NULL