aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--readme.txt4
-rw-r--r--src/chmtx.c6
-rw-r--r--test/test.c2
-rw-r--r--test/test.mk6
-rw-r--r--test/testcond.c113
-rw-r--r--test/testcond.h25
-rw-r--r--test/testmtx.c133
7 files changed, 146 insertions, 143 deletions
diff --git a/readme.txt b/readme.txt
index c29dffb74..ef9fcf4e0 100644
--- a/readme.txt
+++ b/readme.txt
@@ -73,7 +73,11 @@ Win32-MinGW - ChibiOS/RT simulator and demo into a WIN32 process,
*****************************************************************************
*** 1.1.2unstable ***
+- FIX: Fixed priority inheritance problem with condvars (bug 2674756) and
+ added a specific test case to the test suite (backported in stable branch).
- FIX: Removed unused chSysPuts() macro (bug 2672678).
+- Removed testcond.c|h and moved the test cases into testmtx.c. Mutexes and
+ condvars have to be tested together.
- Added architecture diagram to the documentation.
*** 1.1.1unstable ***
diff --git a/src/chmtx.c b/src/chmtx.c
index 396825735..b1d32d220 100644
--- a/src/chmtx.c
+++ b/src/chmtx.c
@@ -93,6 +93,12 @@ void chMtxLockS(Mutex *mp) {
/* boost the owner of this mutex if needed */
tp = tp->p_wtmtxp->m_owner;
continue;
+#if CH_USE_CONDVARS
+ case PRWTCOND:
+ /* Requeues tp with its new priority on the condvar queue. */
+ prio_insert(dequeue(tp), &tp->p_wtcondp->c_queue);
+ break;
+#endif
#if CH_USE_SEMAPHORES_PRIORITY
case PRWTSEM:
/* Requeues tp with its new priority on the semaphore queue. */
diff --git a/test/test.c b/test/test.c
index 15e23e79c..be3c8d9c5 100644
--- a/test/test.c
+++ b/test/test.c
@@ -23,7 +23,6 @@
#include "testrdy.h"
#include "testsem.h"
#include "testmtx.h"
-#include "testcond.h"
#include "testmsg.h"
#include "testmbox.h"
#include "testevt.h"
@@ -39,7 +38,6 @@ static const struct testcase **patterns[] = {
patternrdy,
patternsem,
patternmtx,
- patterncond,
patternmsg,
patternmbox,
patternevt,
diff --git a/test/test.mk b/test/test.mk
index 6cce48f2a..9f423de64 100644
--- a/test/test.mk
+++ b/test/test.mk
@@ -1,8 +1,8 @@
# List of all the ChibiOS/RT test files.
TESTSRC = ../../test/test.c ../../test/testrdy.c ../../test/testsem.c \
- ../../test/testmtx.c ../../test/testcond.c ../../test/testmsg.c \
- ../../test/testmbox.c ../../test/testevt.c ../../test/testheap.c \
- ../../test/testpools.c ../../test/testdyn.c ../../test/testbmk.c
+ ../../test/testmtx.c ../../test/testmsg.c ../../test/testmbox.c \
+ ../../test/testevt.c ../../test/testheap.c ../../test/testpools.c \
+ ../../test/testdyn.c ../../test/testbmk.c
# Required include directories
TESTINC = ../../test
diff --git a/test/testcond.c b/test/testcond.c
deleted file mode 100644
index dff5d2c29..000000000
--- a/test/testcond.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
-
- This file is part of ChibiOS/RT.
-
- ChibiOS/RT is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- ChibiOS/RT is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <ch.h>
-
-#include "test.h"
-
-#if CH_USE_CONDVARS && CH_USE_MUTEXES
-
-static Mutex m1;
-static CondVar c1;
-
-static char *cond1_gettest(void) {
-
- return "CondVar, signal test";
-}
-
-static void cond1_setup(void) {
-
- chCondInit(&c1);
- chMtxInit(&m1);
-}
-
-static msg_t thread1(void *p) {
-
- chMtxLock(&m1);
- chCondWait(&c1);
- test_emit_token(*(char *)p);
- chMtxUnlock();
- return 0;
-}
-
-static void cond1_execute(void) {
-
- // Bacause priority inheritance.
- tprio_t prio = chThdGetPriority();
- threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prio+1, thread1, "E");
- threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prio+2, thread1, "D");
- threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prio+3, thread1, "C");
- threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prio+4, thread1, "B");
- threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prio+5, thread1, "A");
- test_assert(prio == chThdGetPriority(), "#1"); /* Priority return failure.*/
- chCondSignal(&c1);
- chCondSignal(&c1);
- chCondSignal(&c1);
- chCondSignal(&c1);
- chCondSignal(&c1);
- test_wait_threads();
- test_assert_sequence("ABCDE");
-}
-
-const struct testcase testcond1 = {
- cond1_gettest,
- cond1_setup,
- NULL,
- cond1_execute
-};
-
-static char *cond2_gettest(void) {
-
- return "CondVar, broadcast test";
-}
-
-static void cond2_execute(void) {
-
- // Bacause priority inheritance.
- tprio_t prio = chThdGetPriority();
- threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prio+1, thread1, "E");
- threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prio+2, thread1, "D");
- threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prio+3, thread1, "C");
- threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prio+4, thread1, "B");
- threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prio+5, thread1, "A");
- test_assert(prio == chThdGetPriority(), "#1"); /* Priority return failure.*/
- chCondBroadcast(&c1);
- test_wait_threads();
- test_assert_sequence("ABCDE");
-}
-
-const struct testcase testcond2 = {
- cond2_gettest,
- NULL,
- NULL,
- cond2_execute
-};
-
-#endif /* CH_USE_CONDVARS && CH_USE_MUTEXES */
-
-/*
- * Test sequence for condvars pattern.
- */
-const struct testcase * const patterncond[] = {
-#if CH_USE_CONDVARS && CH_USE_MUTEXES
- &testcond1,
- &testcond2,
-#endif
- NULL
-};
diff --git a/test/testcond.h b/test/testcond.h
deleted file mode 100644
index b07aa804e..000000000
--- a/test/testcond.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
-
- This file is part of ChibiOS/RT.
-
- ChibiOS/RT is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- ChibiOS/RT is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _TESTCOND_H_
-#define _TESTCOND_H_
-
-extern const struct testcase *patterncond[];
-
-#endif /* _TESTCOND_H_ */
diff --git a/test/testmtx.c b/test/testmtx.c
index e08aab5be..c8050e887 100644
--- a/test/testmtx.c
+++ b/test/testmtx.c
@@ -26,6 +26,7 @@
#define ALLOWED_DELAY 5
static Mutex m1, m2;
+static CondVar c1;
static char *mtx1_gettest(void) {
@@ -213,6 +214,133 @@ const struct testcase testmtx3 = {
mtx3_execute
};
+#if CH_USE_CONDVARS
+static char *mtx4_gettest(void) {
+
+ return "CondVar, signal test";
+}
+
+static void mtx4_setup(void) {
+
+ chCondInit(&c1);
+ chMtxInit(&m1);
+}
+
+static msg_t thread10(void *p) {
+
+ chMtxLock(&m1);
+ chCondWait(&c1);
+ test_emit_token(*(char *)p);
+ chMtxUnlock();
+ return 0;
+}
+
+static void mtx4_execute(void) {
+
+ tprio_t prio = chThdGetPriority();
+ threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prio+1, thread10, "E");
+ threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prio+2, thread10, "D");
+ threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prio+3, thread10, "C");
+ threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prio+4, thread10, "B");
+ threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prio+5, thread10, "A");
+ chCondSignal(&c1);
+ chCondSignal(&c1);
+ chCondSignal(&c1);
+ chCondSignal(&c1);
+ chCondSignal(&c1);
+ test_wait_threads();
+ test_assert_sequence("ABCDE");
+}
+
+const struct testcase testmtx4 = {
+ mtx4_gettest,
+ mtx4_setup,
+ NULL,
+ mtx4_execute
+};
+
+static char *mtx5_gettest(void) {
+
+ return "CondVar, broadcast test";
+}
+
+static void mtx5_setup(void) {
+
+ chCondInit(&c1);
+ chMtxInit(&m1);
+}
+
+static void mtx5_execute(void) {
+
+ // Bacause priority inheritance.
+ tprio_t prio = chThdGetPriority();
+ threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prio+1, thread10, "E");
+ threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prio+2, thread10, "D");
+ threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prio+3, thread10, "C");
+ threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prio+4, thread10, "B");
+ threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prio+5, thread10, "A");
+ chCondBroadcast(&c1);
+ test_wait_threads();
+ test_assert_sequence("ABCDE");
+}
+
+const struct testcase testmtx5 = {
+ mtx5_gettest,
+ mtx5_setup,
+ NULL,
+ mtx5_execute
+};
+
+static char *mtx6_gettest(void) {
+
+ return "CondVar, inheritance boost test";
+}
+
+static void mtx6_setup(void) {
+
+ chCondInit(&c1);
+ chMtxInit(&m1);
+ chMtxInit(&m2);
+}
+
+static msg_t thread11(void *p) {
+
+ chMtxLock(&m2);
+ chMtxLock(&m1);
+ chCondWait(&c1);
+ test_emit_token(*(char *)p);
+ chMtxUnlock();
+ chMtxUnlock();
+ return 0;
+}
+
+static msg_t thread12(void *p) {
+
+ chMtxLock(&m2);
+ test_emit_token(*(char *)p);
+ chMtxUnlock();
+ return 0;
+}
+
+static void mtx6_execute(void) {
+
+ tprio_t prio = chThdGetPriority();
+ threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prio+1, thread11, "A");
+ threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prio+2, thread10, "C");
+ threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prio+3, thread12, "B");
+ chCondSignal(&c1);
+ chCondSignal(&c1);
+ test_wait_threads();
+ test_assert_sequence("ABC");
+}
+
+const struct testcase testmtx6 = {
+ mtx6_gettest,
+ mtx6_setup,
+ NULL,
+ mtx6_execute
+};
+#endif /* CH_USE_CONDVARS */
#endif /* CH_USE_MUTEXES */
/*
@@ -223,6 +351,11 @@ const struct testcase * const patternmtx[] = {
&testmtx1,
&testmtx2,
&testmtx3,
+#if CH_USE_CONDVARS
+ &testmtx4,
+ &testmtx5,
+ &testmtx6,
+#endif
#endif
NULL
};