git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@30 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2007-10-03 17:14:03 +00:00
parent 1b269aa139
commit 2310f80695
16 changed files with 364 additions and 34 deletions

View File

@ -63,6 +63,10 @@
* in the kernel.*/
#define CH_USE_SEMAPHORES
/** Configuration option: if specified then the Semaphores atomic Signal+Wait
* APIs are included in the kernel.*/
#define CH_USE_SEMSW
/** Configuration option: if specified then the Semaphores with timeout APIs
* are included in the kernel.
* @note requires \p CH_USE_SEMAPHORES.

View File

@ -182,6 +182,13 @@
RelativePath="..\..\ports\Win32\simcom.c">
</File>
</Filter>
<Filter
Name="test"
Filter="">
<File
RelativePath="..\..\test\test.c">
</File>
</Filter>
</Filter>
<Filter
Name="Header Files"

View File

@ -68,6 +68,10 @@
* in the kernel.*/
#define CH_USE_SEMAPHORES
/** Configuration option: if specified then the Semaphores atomic Signal+Wait
* APIs are included in the kernel.*/
#define CH_USE_SEMSW
/** Configuration option: if specified then the Semaphores with timeout APIs
* are included in the kernel.
* @note requires \p CH_USE_SEMAPHORES.
@ -134,11 +138,11 @@
/** Configuration option: Frequency of the system timer that drives the system
* ticks. This also defines the system time unit.*/
#define CH_FREQUENCY 100
#define CH_FREQUENCY 1000
/** Configuration option: This constant is the number of ticks allowed for the
* threads before preemption occurs.*/
#define CH_TIME_QUANTUM 10
#define CH_TIME_QUANTUM 20
/** Configuration option: Defines a CPU register to be used as storage for the
* global \p currp variable. Caching this variable in a register can greatly

View File

@ -31,11 +31,13 @@ static BYTE8 iarea[UserStackSize(2048)];
static ULONG32 cdguard;
static BYTE8 cdarea[UserStackSize(2048)];
static Thread *cdtp;
static t_msg WatchdogThread(void *arg);
static t_msg ConsoleThread(void *arg);
static t_msg InitThread(void *arg);
t_msg TestThread(void *p);
void InitCore(void);
extern FullDuplexDriver COM1, COM2;
@ -73,7 +75,7 @@ static t_msg WatchdogThread(void *arg) {
printf("Halted by watchdog");
chSysHalt();
}
chThdSleep(5);
chThdSleep(50);
}
return 0;
}
@ -144,7 +146,7 @@ static t_msg HelloWorldThread(void *arg) {
for (i = 0; i < 100; i++) {
PrintLineFDD(sd, "Hello World\r\n");
c = chFDDGetTimeout(sd, 33);
c = chFDDGetTimeout(sd, 333);
switch (c) {
case -1:
continue;
@ -154,7 +156,7 @@ static t_msg HelloWorldThread(void *arg) {
PrintLineFDD(sd, "^C\r\n");
return 0;
default:
chThdSleep(33);
chThdSleep(333);
}
}
return 0;
@ -202,6 +204,7 @@ static t_msg ShellThread(void *arg) {
PrintLineFDD(sd, " exit - Logout from ChibiOS/RT\r\n");
PrintLineFDD(sd, " time - Prints the system timer value\r\n");
PrintLineFDD(sd, " hello - Runs the Hello World demo thread\r\n");
PrintLineFDD(sd, " test - Runs the System Test thread\r\n");
}
else if (stricmp(lp, "exit") == 0) {
if (checkend(sd))
@ -223,6 +226,14 @@ static t_msg ShellThread(void *arg) {
if (chThdWait(tp))
break; // Lost connection while executing the hello thread.
}
else if (stricmp(lp, "test") == 0) {
if (checkend(sd))
continue;
tp = chThdCreate(NORMALPRIO, 0, tarea, sizeof(tarea),
TestThread, arg);
if (chThdWait(tp))
break; // Lost connection while executing the hello thread.
}
else {
PrintLineFDD(sd, lp);
PrintLineFDD(sd, " ?\r\n");
@ -281,7 +292,7 @@ static void COM2Handler(t_eventid id) {
static t_evhandler fhandlers[2] = {
COM1Handler,
COM2Handler
};
};
/*
* Init-like thread, it starts the shells and handles their termination.

View File

@ -57,7 +57,7 @@ UADEFS =
# List C source files here
SRC = chcore.c demo.c \
../../ports/win32/simcom.c \
../../test/test.c ../../ports/win32/simcom.c \
../../src/chinit.c ../../src/chlists.c ../../src/chdelta.c ../../src/chschd.c \
../../src/chthreads.c ../../src/chsem.c ../../src/chevents.c ../../src/chmsg.c \
../../src/chsleep.c ../../src/chqueues.c ../../src/chserial.c

View File

@ -68,6 +68,10 @@
* in the kernel.*/
#define CH_USE_SEMAPHORES
/** Configuration option: if specified then the Semaphores atomic Signal+Wait
* APIs are included in the kernel.*/
#define CH_USE_SEMSW
/** Configuration option: if specified then the Semaphores with timeout APIs
* are included in the kernel.
* @note requires \p CH_USE_SEMAPHORES.
@ -134,11 +138,11 @@
/** Configuration option: Frequency of the system timer that drives the system
* ticks. This also defines the system time unit.*/
#define CH_FREQUENCY 100
#define CH_FREQUENCY 1000
/** Configuration option: This constant is the number of ticks allowed for the
* threads before preemption occurs.*/
#define CH_TIME_QUANTUM 10
#define CH_TIME_QUANTUM 20
/** Configuration option: Defines a CPU register to be used as storage for the
* global \p currp variable. Caching this variable in a register can greatly

View File

@ -52,7 +52,7 @@ void InitCore(void) {
exit(1);
}
printf("Win32 ChobiOS/RT simulator\n\n");
printf("Win32 ChibiOS/RT simulator\n\n");
printf("Thread structure %d bytes\n", sizeof(Thread));
if (!QueryPerformanceFrequency(&slice)) {
printf("QueryPerformanceFrequency() error");

View File

@ -39,5 +39,5 @@
.p2align 4,,15
.globl @threadstart@0
@threadstart@0:
push %ecx
push %eax
call _chThdExit

View File

@ -36,6 +36,8 @@ static t_msg WatchdogThread(void *arg);
static t_msg ConsoleThread(void *arg);
static t_msg InitThread(void *arg);
t_msg TestThread(void *p);
void InitCore(void);
extern FullDuplexDriver COM1, COM2;
@ -73,7 +75,7 @@ static t_msg WatchdogThread(void *arg) {
printf("Halted by watchdog");
chSysHalt();
}
chThdSleep(5);
chThdSleep(50);
}
return 0;
}
@ -144,7 +146,7 @@ static t_msg HelloWorldThread(void *arg) {
for (i = 0; i < 100; i++) {
PrintLineFDD(sd, "Hello World\r\n");
c = chFDDGetTimeout(sd, 33);
c = chFDDGetTimeout(sd, 333);
switch (c) {
case -1:
continue;
@ -154,7 +156,7 @@ static t_msg HelloWorldThread(void *arg) {
PrintLineFDD(sd, "^C\r\n");
return 0;
default:
chThdSleep(33);
chThdSleep(333);
}
}
return 0;
@ -202,6 +204,7 @@ static t_msg ShellThread(void *arg) {
PrintLineFDD(sd, " exit - Logout from ChibiOS/RT\r\n");
PrintLineFDD(sd, " time - Prints the system timer value\r\n");
PrintLineFDD(sd, " hello - Runs the Hello World demo thread\r\n");
PrintLineFDD(sd, " test - Runs the System Test thread\r\n");
}
else if (stricmp(lp, "exit") == 0) {
if (checkend(sd))
@ -223,6 +226,14 @@ static t_msg ShellThread(void *arg) {
if (chThdWait(tp))
break; // Lost connection while executing the hello thread.
}
else if (stricmp(lp, "test") == 0) {
if (checkend(sd))
continue;
tp = chThdCreate(NORMALPRIO, 0, tarea, sizeof(tarea),
TestThread, arg);
if (chThdWait(tp))
break; // Lost connection while executing the hello thread.
}
else {
PrintLineFDD(sd, lp);
PrintLineFDD(sd, " ?\r\n");

View File

@ -241,7 +241,8 @@ PREDEFINED = __JUST_STUBS__ \
CH_USE_SERIAL_HALFDUPLEX \
CH_USE_MESSAGES \
CH_USE_MESSAGES_TIMEOUT \
CH_USE_MESSAGES_EVENT
CH_USE_MESSAGES_EVENT \
CH_USE_SEMSW
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------

View File

@ -33,23 +33,36 @@ LPC214x-GCC - ChibiOS/RT port for ARM7 LPC2148, the demo targets the
*****************************************************************************
*** 0.3.1 ***
- Test program added to the MinGW and MSVS demos. Telnet the demo and type
"test" at the "ch>" prompt. The test performs integrity tests on the main
ChibiOS/RT functionalities.
The test code is also a good example of APIs usage and ChibiOS/RT behavior.
- Fixed bug in chEvtWaitTimeout(), the timeout code performed an useless
dequeue operation.
- Fixed a bug in chSemWaitTimeoutS() and chSemWaitTimeout(), the semaphore
counter was not atomically updated on a timeout condition.
- Fixed bug on RT semaphores, the priority queuing was broken.
- Fixed a bug in the MinGW demo, the chThdExit() code was not correctly
reported to the thread waiting in chThdWait().
- Fixed a function declaration in semaphores.h.
- Lists code moved into chlists.c from various other places optimized and
reorganized.
- The list of the threads waiting in chThdWait() is now a single link list,
this saves some space.
- Cleaned the template files code, the files contained some obsolete
declarations.
- Code optimization in scSemSignalWait().
- Code optimization in chSemWaitTimeoutS(), chSemWaitTimeout() and
chSemSignalWait().
- Code optimization in chEvtSend().
- Code optimization in chVTDoTickI().
- Added a Semaphore pointer to the Thread structure, this allows to know on
which semaphore a thread is waiting on. It takes no space because it is
located in the union inside the Thread structure. This also allowed a minor
optimization inside chSemWaitTimeout() and chSemWaitTimeoutS().
- Changed the priority type to unsigned in order to make it compatible
with a byte value, this is very important for 8 bits architectures.
- Fixed bug in chEvtWaitTimeout(), the timeout code performed a useless
dequeue operation.
- Fixed bug on RT semaphores, the priority queuing was broken.
- Modified the MinGW and MSVS demos to use 1ms ticks instead of 10ms as
before.
*** 0.3.0 ***
- ChibiOS/RT goes beta.

View File

@ -138,13 +138,9 @@ t_msg chSemWaitTimeout(Semaphore *sp, t_time time) {
fifo_insert(currp, &sp->s_queue);
currp->p_semp = sp;
chSchGoSleepI(PRWTSEM);
msg = currp->p_rdymsg; // Note, got value *before* invoking CH_LEAVE_SYSTEM().
if (!vt.vt_func) {
chSysUnlock();
return msg;
}
chVTResetI(&vt);
msg = currp->p_rdymsg;
if (vt.vt_func)
chVTResetI(&vt);
chSysUnlock();
return msg;
@ -173,9 +169,8 @@ t_msg chSemWaitTimeoutS(Semaphore *sp, t_time time) {
fifo_insert(currp, &sp->s_queue);
currp->p_semp = sp;
chSchGoSleepI(PRWTSEM);
if (!vt.vt_func)
return currp->p_rdymsg;
chVTResetI(&vt);
if (vt.vt_func)
chVTResetI(&vt);
return currp->p_rdymsg;
}
return RDY_OK;
@ -211,6 +206,7 @@ void chSemSignalI(Semaphore *sp) {
chSchReadyI(fifo_remove(&sp->s_queue));
}
#ifdef CH_USE_SEMSW
/**
* Performs atomic signal and wait operations on two semaphores.
* @param sps pointer to a \p Semaphore structure to be signaled
@ -235,6 +231,7 @@ void chSemSignalWait(Semaphore *sps, Semaphore *spw) {
chSysUnlock();
}
#endif /* CH_USE_SEMSW */
#ifdef CH_USE_RT_SEMAPHORES
/*
@ -299,6 +296,7 @@ void chSemLowerPrioSignal(Semaphore *sp) {
chSysUnlock();
}
#ifdef CH_USE_SEMSW
/**
* Performs atomic signal and wait operations on two semaphores with priority
* boost.
@ -326,7 +324,7 @@ void chSemRaisePrioSignalWait(Semaphore *sps, Semaphore *spw) {
if (!currp->p_rtcnt++)
currp->p_prio += MEPRIO;
chSchRescheduleI();
chSchRescheduleI(); // Really needed ?
}
chSysUnlock();
@ -360,6 +358,7 @@ void chSemLowerPrioSignalWait(Semaphore *sps, Semaphore *spw) {
chSysUnlock();
}
#endif /* CH_USE_SEMSW */
#endif /* CH_USE_RT_SEMAPHORES */

View File

@ -77,8 +77,7 @@ extern DeltaList dlist;
while (!(vtp = dlist.dl_next)->vt_dtime) { \
t_vtfunc fn = vtp->vt_func; \
vtp->vt_func = 0; \
vtp->vt_prev->vt_next = vtp->vt_next; \
vtp->vt_next->vt_prev = vtp->vt_prev; \
(vtp->vt_next->vt_prev = (VirtualTimer *)&dlist)->vt_next = vtp->vt_next; \
fn(vtp->vt_par); \
} \
}

View File

@ -46,7 +46,7 @@ t_msg chSemWaitTimeout(Semaphore *sp, t_time time);
t_msg chSemWaitTimeoutS(Semaphore *sp, t_time time);
void chSemSignal(Semaphore *sp);
void chSemSignalI(Semaphore *sp);
void chSignalWait(Semaphore *sps, Semaphore *spw);
void chSemSignalWait(Semaphore *sps, Semaphore *spw);
#ifdef CH_USE_RT_SEMAPHORES
void chSemRaisePrioWait(Semaphore *sp);

View File

@ -64,6 +64,10 @@
* in the kernel.*/
#define CH_USE_SEMAPHORES
/** Configuration option: if specified then the Semaphores atomic Signal+Wait
* APIs are included in the kernel.*/
#define CH_USE_SEMSW
/** Configuration option: if specified then the Semaphores with timeout APIs
* are included in the kernel.
* @note requires \p CH_USE_SEMAPHORES.

273
test/test.c Normal file
View File

@ -0,0 +1,273 @@
/*
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>
#if defined(WIN32) && defined(_DEBUG)
static BYTE8 wsT1[UserStackSize(512)];
static BYTE8 wsT2[UserStackSize(512)];
static BYTE8 wsT3[UserStackSize(512)];
static BYTE8 wsT4[UserStackSize(512)];
static BYTE8 wsT5[UserStackSize(512)];
#else
static BYTE8 wsT1[UserStackSize(64)];
static BYTE8 wsT2[UserStackSize(64)];
static BYTE8 wsT3[UserStackSize(64)];
static BYTE8 wsT4[UserStackSize(64)];
static BYTE8 wsT5[UserStackSize(64)];
#endif
static Thread *t1, *t2, *t3, *t4, *t5;
static FullDuplexDriver *comp;
static Semaphore sem1, sem2;
static void wait(void) {
chThdWait(t1);
chThdWait(t2);
chThdWait(t3);
chThdWait(t4);
chThdWait(t5);
}
static void println(char *msgp) {
while (*msgp)
chFDDPut(comp, *msgp++);
chFDDPut(comp, '\r');
chFDDPut(comp, '\n');
}
t_msg Thread1(void *p) {
chFDDPut(comp, *(BYTE8 *)p);
return 0;
}
t_msg Thread2(void *p) {
chSemWait(&sem1);
chFDDPut(comp, *(BYTE8 *)p);
return 0;
}
t_msg Thread3(void *p) {
chSemRaisePrioWait(&sem1);
chFDDPut(comp, *(BYTE8 *)p);
return 0;
}
t_msg Thread4(void *p) {
chSemWait(&sem1);
chFDDPut(comp, *(BYTE8 *)p);
/*
* NOTE: chSemSignalWait() is not the same of chSemSignal()+chSemWait().
* The former is performed atomically, try it.
*/
chSemSignalWait(&sem1, &sem2);
// chSemSignal(&sem1);
// chSemWait(&sem2);
chFDDPut(comp, *(BYTE8 *)p);
chSemSignal(&sem2);
return 0;
}
t_msg Thread5(void *p) {
chSemWait(&sem1);
chFDDPut(comp, *(BYTE8 *)p);
chSemRaisePrioSignalWait(&sem1, &sem2);
// chSemSignal(&sem1);
// chSemRaisePrioWait(&sem2);
chFDDPut(comp, *(BYTE8 *)p);
chSemLowerPrioSignal(&sem2);
return 0;
}
t_msg Thread6(void *p) {
t_msg msg;
int i;
for (i = 0; i < 5; i++) {
msg = chMsgSend(p, 'A' + i);
chFDDPut(comp, msg);
}
chMsgSend(p, 0);
return 0;
}
t_msg Thread7(void *p) {
// NOTE, this thread does not serve messages this causes the client to
// timeout.
chThdSleep(3000);
return 0;
}
/**
* Tester thread, this thread must be created with priority \p NORMALPRIO.
*/
t_msg TestThread(void *p) {
t_msg msg;
int i;
comp = p;
/*
* Ready list ordering test.
*/
println("*** Ready List, priority enqueuing test #1, you should read ABCDE:");
t5 = chThdCreate(NORMALPRIO-5, 0, wsT5, sizeof(wsT5), Thread1, "E");
t4 = chThdCreate(NORMALPRIO-4, 0, wsT4, sizeof(wsT4), Thread1, "D");
t3 = chThdCreate(NORMALPRIO-3, 0, wsT3, sizeof(wsT3), Thread1, "C");
t2 = chThdCreate(NORMALPRIO-2, 0, wsT2, sizeof(wsT2), Thread1, "B");
t1 = chThdCreate(NORMALPRIO-1, 0, wsT1, sizeof(wsT1), Thread1, "A");
wait();
println("");
println("*** Ready List, priority enqueuing test #2, you should read ABCDE:");
t4 = chThdCreate(NORMALPRIO-4, 0, wsT4, sizeof(wsT4), Thread1, "D");
t5 = chThdCreate(NORMALPRIO-5, 0, wsT5, sizeof(wsT5), Thread1, "E");
t1 = chThdCreate(NORMALPRIO-1, 0, wsT1, sizeof(wsT1), Thread1, "A");
t2 = chThdCreate(NORMALPRIO-2, 0, wsT2, sizeof(wsT2), Thread1, "B");
t3 = chThdCreate(NORMALPRIO-3, 0, wsT3, sizeof(wsT3), Thread1, "C");
wait();
println("");
/*
* Semaphores test.
*/
chSemInit(&sem1, 0);
println("*** Semaphores, FIFO enqueuing test, you should read ABCDE:");
t1 = chThdCreate(NORMALPRIO+5, 0, wsT1, sizeof(wsT1), Thread2, "A");
t2 = chThdCreate(NORMALPRIO+1, 0, wsT2, sizeof(wsT2), Thread2, "B");
t3 = chThdCreate(NORMALPRIO+3, 0, wsT3, sizeof(wsT3), Thread2, "C");
t4 = chThdCreate(NORMALPRIO+4, 0, wsT4, sizeof(wsT4), Thread2, "D");
t5 = chThdCreate(NORMALPRIO+2, 0, wsT5, sizeof(wsT5), Thread2, "E");
chSemSignal(&sem1);
chSemSignal(&sem1);
chSemSignal(&sem1);
chSemSignal(&sem1);
chSemSignal(&sem1);
wait();
println("");
println("*** Semaphores, priority enqueuing test #1, you should read ABCDE:");
t5 = chThdCreate(NORMALPRIO+1, 0, wsT5, sizeof(wsT5), Thread3, "E");
t4 = chThdCreate(NORMALPRIO+2, 0, wsT4, sizeof(wsT4), Thread3, "D");
t3 = chThdCreate(NORMALPRIO+3, 0, wsT3, sizeof(wsT3), Thread3, "C");
t2 = chThdCreate(NORMALPRIO+4, 0, wsT2, sizeof(wsT2), Thread3, "B");
t1 = chThdCreate(NORMALPRIO+5, 0, wsT1, sizeof(wsT1), Thread3, "A");
chSemLowerPrioSignal(&sem1);
chSemLowerPrioSignal(&sem1);
chSemLowerPrioSignal(&sem1);
chSemLowerPrioSignal(&sem1);
chSemLowerPrioSignal(&sem1);
wait();
println("");
println("*** Semaphores, priority enqueuing test #2, you should read ABCDE:");
t4 = chThdCreate(NORMALPRIO+2, 0, wsT4, sizeof(wsT4), Thread3, "D");
t5 = chThdCreate(NORMALPRIO+1, 0, wsT5, sizeof(wsT5), Thread3, "E");
t1 = chThdCreate(NORMALPRIO+5, 0, wsT1, sizeof(wsT1), Thread3, "A");
t2 = chThdCreate(NORMALPRIO+4, 0, wsT2, sizeof(wsT2), Thread3, "B");
t3 = chThdCreate(NORMALPRIO+3, 0, wsT3, sizeof(wsT3), Thread3, "C");
chSemLowerPrioSignal(&sem1);
chSemLowerPrioSignal(&sem1);
chSemLowerPrioSignal(&sem1);
chSemLowerPrioSignal(&sem1);
chSemLowerPrioSignal(&sem1);
wait();
println("");
println("*** Semaphores, atomicity test #1, you should read ABCDEABCDE:");
chSemInit(&sem1, 0);
chSemInit(&sem2, 1);
t1 = chThdCreate(NORMALPRIO+1, 0, wsT1, sizeof(wsT1), Thread4, "A");
t2 = chThdCreate(NORMALPRIO+2, 0, wsT2, sizeof(wsT2), Thread4, "B");
t3 = chThdCreate(NORMALPRIO+3, 0, wsT3, sizeof(wsT3), Thread4, "C");
t4 = chThdCreate(NORMALPRIO+4, 0, wsT4, sizeof(wsT4), Thread4, "D");
t5 = chThdCreate(NORMALPRIO+5, 0, wsT5, sizeof(wsT5), Thread4, "E");
chSemSignal(&sem1);
wait();
println("");
println("*** Semaphores, atomicity test #2, you should read ABCDEABCDE:");
chSemInit(&sem1, 0);
chSemInit(&sem2, 1);
t1 = chThdCreate(NORMALPRIO+1, 0, wsT1, sizeof(wsT1), Thread4, "A");
t2 = chThdCreate(NORMALPRIO+5, 0, wsT2, sizeof(wsT2), Thread4, "B");
t3 = chThdCreate(NORMALPRIO+2, 0, wsT3, sizeof(wsT3), Thread4, "C");
t4 = chThdCreate(NORMALPRIO+4, 0, wsT4, sizeof(wsT4), Thread4, "D");
t5 = chThdCreate(NORMALPRIO+3, 0, wsT5, sizeof(wsT5), Thread4, "E");
chSemSignal(&sem1);
wait();
println("");
println("*** Semaphores, atomicity test #3, you should read AABBCCDDEE:");
chSemInit(&sem1, 0);
chSemInit(&sem2, 1);
t1 = chThdCreate(NORMALPRIO+1, 0, wsT1, sizeof(wsT1), Thread5, "A");
t2 = chThdCreate(NORMALPRIO+2, 0, wsT2, sizeof(wsT2), Thread5, "B");
t3 = chThdCreate(NORMALPRIO+3, 0, wsT3, sizeof(wsT3), Thread5, "C");
t4 = chThdCreate(NORMALPRIO+4, 0, wsT4, sizeof(wsT4), Thread5, "D");
t5 = chThdCreate(NORMALPRIO+5, 0, wsT5, sizeof(wsT5), Thread5, "E");
chSemSignal(&sem1);
wait();
println("");
println("*** Semaphores, atomicity test #4, you should read AABBCCDDEE:");
chSemInit(&sem1, 0);
chSemInit(&sem2, 1);
t1 = chThdCreate(NORMALPRIO+1, 0, wsT1, sizeof(wsT1), Thread5, "A");
t2 = chThdCreate(NORMALPRIO+5, 0, wsT2, sizeof(wsT2), Thread5, "B");
t3 = chThdCreate(NORMALPRIO+2, 0, wsT3, sizeof(wsT3), Thread5, "C");
t4 = chThdCreate(NORMALPRIO+4, 0, wsT4, sizeof(wsT4), Thread5, "D");
t5 = chThdCreate(NORMALPRIO+3, 0, wsT5, sizeof(wsT5), Thread5, "E");
chSemSignal(&sem1);
wait();
println("");
println("*** Semaphores, timeout test, you should read ABCDE (slowly):");
chSemInit(&sem1, 0);
for (i = 0; i < 5; i++) {
chFDDPut(comp, 'A'+i);
chSemWaitTimeout(&sem1, 500);
}
println("");
/*
* Messages test.
*/
println("*** Messages, dispatch test, you should read AABBCCDDEE:");
t1 = chThdCreate(NORMALPRIO-1, 0, wsT1, sizeof(wsT1), Thread6, chThdSelf());
do {
chMsgRelease(msg = chMsgWait());
if (msg)
chFDDPut(comp, msg);
} while (msg);
chThdWait(t1);
println("");
println("*** Messages, timeout test, you should read ABCDE (slowly):");
t1 = chThdCreate(NORMALPRIO-1, 0, wsT1, sizeof(wsT1), Thread7, chThdSelf());
for (i = 0; i < 5; i++) {
chFDDPut(comp, 'A'+i);
chMsgSendTimeout(t1, 'A'+i, 500);
}
chMsgSendTimeout(t1, 0, 500);
chThdWait(t1);
println("");
println("\r\nTest complete");
return 0;
}