diff options
| -rw-r--r-- | readme.txt | 4 | ||||
| -rw-r--r-- | src/chmtx.c | 6 | ||||
| -rw-r--r-- | test/test.c | 2 | ||||
| -rw-r--r-- | test/test.mk | 6 | ||||
| -rw-r--r-- | test/testcond.c | 113 | ||||
| -rw-r--r-- | test/testcond.h | 25 | ||||
| -rw-r--r-- | test/testmtx.c | 133 | 
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
  };
  | 
