* [Xenomai] FreeRTOS skin
@ 2014-05-04 16:59 Matthias Schneider
2014-05-04 18:42 ` Gilles Chanteperdrix
2014-05-05 10:33 ` Philippe Gerum
0 siblings, 2 replies; 21+ messages in thread
From: Matthias Schneider @ 2014-05-04 16:59 UTC (permalink / raw)
To: xenomai@xenomai.org
Hi all,
please find enclosed a patch with a FreeRTOS skin for xenomai-forge I have
been working on for some time. I would like to get some feedback and advice
what still needs to be done to get it accepted in Xenomai. There is a set of
unit tests included and the possibility to download the original FreeRTOS package
in order to run most of its (platform independent) test suite. Until now I have
been working under mercury only. Documentation is available in form of a README
file in lib/freertos/README, which should also be a good starting point. I have
not attached "configure" to the patch, so you will need to recreate the configure
script first before actually running it. You can apply the patch via
git am --keep-cr < 0001-Initial-Freertos-commit.patch
autoreconf
./configure
make
Running the testcases, you might stumble over a
#0 EINVAL in threadobj_unlock_sched(), threadobj.c:59
error, which is due to
http://www.xenomai.org/pipermail/xenomai/2014-May/030821.html
I will try to continue the discussion there.
I do not consider the patch 100% finished yet and I am still working on following topics:
* more testing
* "vStartDynamicPriorityTasks" is not yet passing
* "vCreateBlockTimeTasks"/"vCreateAltBlockTimeTasks" seem to fail sometimes
* it has been ages since I ran the vfile system tests.
* testing with optimization
* test under cobalt (not started yet, still need to get a working setup)
* portBYTE_ALIGNMENT define
* some refactoring (mostly in task.c)
I am publishing this patch already now since I do not want to "finish" it first
before the first review only to find out I have overlooked something that
should have been done differently. Some points to start a discussion are maybe:
* what kind of documentation is still missing
* correct placement of CANCEL_DEFER and CANCEL_RESTORE
* priority of new threads during prologue (will start conversation based on
http://www.xenomai.org/pipermail/xenomai/2014-February/030117.html
)
I am doing this in my free time, so please be patient when I am not responding
right away...
Regards,
Matthias
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Initial-Freertos-commit.patch.gz
Type: application/x-gzip
Size: 34769 bytes
Desc: not available
URL: <http://www.xenomai.org/pipermail/xenomai/attachments/20140504/ed4fc483/attachment.bin>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Xenomai] FreeRTOS skin
2014-05-04 16:59 [Xenomai] FreeRTOS skin Matthias Schneider
@ 2014-05-04 18:42 ` Gilles Chanteperdrix
2014-05-04 21:22 ` Matthias Schneider
2014-05-05 10:33 ` Philippe Gerum
1 sibling, 1 reply; 21+ messages in thread
From: Gilles Chanteperdrix @ 2014-05-04 18:42 UTC (permalink / raw)
To: Matthias Schneider, xenomai@xenomai.org
On 05/04/2014 06:59 PM, Matthias Schneider wrote:
> Hi all,
>
> please find enclosed a patch with a FreeRTOS skin for xenomai-forge I have
> been working on for some time. I would like to get some feedback and advice
> what still needs to be done to get it accepted in Xenomai. There is a set of
> unit tests included and the possibility to download the original FreeRTOS package
> in order to run most of its (platform independent) test suite. Until now I have
> been working under mercury only. Documentation is available in form of a README
> file in lib/freertos/README, which should also be a good starting point. I have
> not attached "configure" to the patch, so you will need to recreate the configure
> script first before actually running it. You can apply the patch via
Hi,
I am not sure that checking whether a type is compatible with void *
will not suddenly avoid the assert check for any pointer type in:
@@ -328,6 +328,7 @@ static inline int pshared_check(void *heap, void *addr)
({ \
type handle; \
assert(__builtin_types_compatible_p(typeof(type), unsigned long) || \
+ __builtin_types_compatible_p(typeof(type), void*) || \
__builtin_types_compatible_p(typeof(type), uintptr_t)); \
assert(ptr == NULL || __memchk(__main_heap, ptr)); \
handle = (type)ptr; \
@@ -337,6 +338,7 @@ static inline int pshared_check(void *heap, void *addr)
({ \
type *ptr; \
assert(__builtin_types_compatible_p(typeof(handle), unsigned long) || \
+ __builtin_types_compatible_p(typeof(handle), void*) || \
__builtin_types_compatible_p(typeof(handle), uintptr_t)); \
ptr = (type *)handle; \
ptr; \
That is a bit complicated:
+#if portBYTE_ALIGNMENT == 8
+ #define portBYTE_ALIGNMENT_MASK (0x0007)
+#endif
+
+#if portBYTE_ALIGNMENT == 4
+ #define portBYTE_ALIGNMENT_MASK (0x0003)
+#endif
+
+#if portBYTE_ALIGNMENT == 2
+ #define portBYTE_ALIGNMENT_MASK (0x0001)
+#endif
+
+#if portBYTE_ALIGNMENT == 1
+ #define portBYTE_ALIGNMENT_MASK (0x0000)
+#endif
+
+#ifndef portBYTE_ALIGNMENT_MASK
+ #error "Invalid portBYTE_ALIGNMENT definition"
+#endif
It seems simpler to me to define portBYTE_ALIGNNMENT_MASK to
portByteALIGNMENT - 1 and trigger an error if portBYTE_ALIGNMENT
is more than 8 or not a power of 2.
On 64 bits machines, long and int are different, so, you probably want
#define portLONG long
To avoid unpleasant surprises in:
+#define portCHAR char
+#define portFLOAT float
+#define portDOUBLE double
+#define portLONG int
I am not sure what is portBYTE_ALIGNEMENT, but I guess sizeof(long) would
make more sense.
+#define portBYTE_ALIGNMENT 8 //FIXME: double check...
I believe there is an error in these macros definition:
This one looks strange:
+#define portNOP() __asm__ __volatile__ ("nop");
If you do not care whether portNOP is a barrier you can drop the "volatile"
otherwise you should add "memory" as clobber.
It may not be a good idea to define errors to overlap with errno errors in:
+/* Error definitions. */
+#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY (-1)
+#define errNO_TASK_TO_RUN (-2)
+#define errQUEUE_BLOCKED (-4)
+#define errQUEUE_YIELD (-5)
I would either define these errors as errno errors or give them values which
do not correspond to any errno constant.
+#define xSemaphoreAltGive(xSemaphore) xSemaphoreGive(xMutex)
+
+#define xSemaphoreGiveFromISR(xSemaphore, pxHigherPriorityTaskWoken) \
+ xSemaphoreGive(xMutex)
+
About the testsuite: does it really make sense to include both the unpatched
testsuite and xenomai-specific patches? I mean if you want to include the
tests in xenomai sources, then include them patched, or do not include them,
and include the patch.
--
Gilles.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Xenomai] FreeRTOS skin
2014-05-04 18:42 ` Gilles Chanteperdrix
@ 2014-05-04 21:22 ` Matthias Schneider
2014-05-05 7:24 ` Philippe Gerum
2014-05-17 14:40 ` Matthias Schneider
0 siblings, 2 replies; 21+ messages in thread
From: Matthias Schneider @ 2014-05-04 21:22 UTC (permalink / raw)
To: Gilles Chanteperdrix, xenomai@xenomai.org
----- Original Message -----
> From: Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>
> To: Matthias Schneider <ma30002000@yahoo.de>; "xenomai@xenomai.org" <xenomai@xenomai.org>
> Cc:
> Sent: Sunday, May 4, 2014 8:42 PM
> Subject: Re: [Xenomai] FreeRTOS skin
>
> On 05/04/2014 06:59 PM, Matthias Schneider wrote:
>> Hi all,
>>
>> please find enclosed a patch with a FreeRTOS skin for xenomai-forge I have
>> been working on for some time. I would like to get some feedback and advice
>> what still needs to be done to get it accepted in Xenomai. There is a set of
>> unit tests included and the possibility to download the original FreeRTOS package
>> in order to run most of its (platform independent) test suite. Until now I have
>> been working under mercury only. Documentation is available in form of a README
>> file in lib/freertos/README, which should also be a good starting point. I have
>> not attached "configure" to the patch, so you will need to recreate the configure
>> script first before actually running it. You can apply the patch via
>
>
> Hi,
>
> I am not sure that checking whether a type is compatible with void *
> will not suddenly avoid the assert check for any pointer type in:
>
> @@ -328,6 +328,7 @@ static inline int pshared_check(void *heap, void *addr)
> ({
> \
> type handle; \
> assert(__builtin_types_compatible_p(typeof(type), unsigned long) || \
> + __builtin_types_compatible_p(typeof(type), void*) || \
> __builtin_types_compatible_p(typeof(type), uintptr_t));
> \
> assert(ptr == NULL || __memchk(__main_heap, ptr)); \
> handle = (type)ptr; \
> @@ -337,6 +338,7 @@ static inline int pshared_check(void *heap, void *addr)
> ({
> \
> type *ptr; \
> assert(__builtin_types_compatible_p(typeof(handle), unsigned long) || \
> + __builtin_types_compatible_p(typeof(handle), void*) || \
> __builtin_types_compatible_p(typeof(handle), uintptr_t));
> \
> ptr = (type *)handle; \
> ptr; \
>
I do agree with the argument; actually originally I had typedef'ed
xQueueHandle, xTaskHandle and xSemaphorehandle as uintptr_t.
However, when compiling original FreeRTOS applications like the
"demo", I ran into many warnings (warning: comparison between
pointer and integer) when comparing the handles to "NULL"
like
if (queueHandle != NULL) {}
Now I see three possibilities:
* stick with the void* and allow it in the check (admittedly
greatly reducing its use)
* change the application code
* suppress warnings when compiling application code (not really
my favorite)
Originally the handles are tyepdef'ed to void* as well.
Any ideas?
> That is a bit complicated:
> +#if portBYTE_ALIGNMENT == 8
> + #define portBYTE_ALIGNMENT_MASK (0x0007)
> +#endif
> +
> +#if portBYTE_ALIGNMENT == 4
> + #define portBYTE_ALIGNMENT_MASK (0x0003)
> +#endif
> +
> +#if portBYTE_ALIGNMENT == 2
> + #define portBYTE_ALIGNMENT_MASK (0x0001)
> +#endif
> +
> +#if portBYTE_ALIGNMENT == 1
> + #define portBYTE_ALIGNMENT_MASK (0x0000)
> +#endif
> +
> +#ifndef portBYTE_ALIGNMENT_MASK
> + #error "Invalid portBYTE_ALIGNMENT definition"
> +#endif
>
> It seems simpler to me to define portBYTE_ALIGNNMENT_MASK to
> portByteALIGNMENT - 1 and trigger an error if portBYTE_ALIGNMENT
> is more than 8 or not a power of 2.
I could change it to:
#if portBYTE_ALIGNMENT > 8 || portBYTE_ALIGNMENT < 1 || \
((portBYTE_ALIGNMENT & ~(portBYTE_ALIGNMENT-1))!=portBYTE_ALIGNMENT)
#error Check portBYTE_ALIGNMENT definition
#endif
#define portBYTE_ALIGNMENT_MASK (portBYTE_ALIGNMENT - 1)
> On 64 bits machines, long and int are different, so, you probably want
> #define portLONG long
> To avoid unpleasant surprises in:
>
> +#define portCHAR char
> +#define portFLOAT float
> +#define portDOUBLE double
> +#define portLONG int
Changed to
#define portLONG long
> I am not sure what is portBYTE_ALIGNEMENT, but I guess sizeof(long) would
> make more sense.
> +#define portBYTE_ALIGNMENT 8 //FIXME: double check...
Seems to be used internally byt the original FreeRTOS implementation,
but is in a public header, so keep it for completeness' sake.
Changing to sizeof(long) as suggested.
> I believe there is an error in these macros definition:
> This one looks strange:
> +#define portNOP() __asm__ __volatile__ ("nop");
>
> If you do not care whether portNOP is a barrier you can drop the "volatile"
> otherwise you should add "memory" as clobber.
The original FreeRTOS implementation is "just" volatile (actually it is
defined exactly the same way as in my header file), so it is a little
difficult to guess the original authors' motives. Since I do not have any
sample code that makes use of this macro, I am not sure of the implications
on existing source code when changing it, independent from removing the volatile
or adding the clobbering.
> It may not be a good idea to define errors to overlap with errno errors in:
> +/* Error definitions. */
> +#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY (-1)
> +#define errNO_TASK_TO_RUN (-2)
> +#define errQUEUE_BLOCKED (-4)
> +#define errQUEUE_YIELD (-5)
>
> I would either define these errors as errno errors or give them values which
> do not correspond to any errno constant.
I could change the first error code to
#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY (-ENOMEM)
and remove the other three codes - they are only needed for the
"CoRoutine"-feature, which is not supported by my xenomai
implementation and were included only for completeness sake.
I have also changed TaskGenericaCreate to actually return
errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY.
> +#define xSemaphoreAltGive(xSemaphore) xSemaphoreGive(xMutex)
> +
> +#define xSemaphoreGiveFromISR(xSemaphore, pxHigherPriorityTaskWoken) \
> + xSemaphoreGive(xMutex)
> +
>
> About the testsuite: does it really make sense to include both the unpatched
> testsuite and xenomai-specific patches? I mean if you want to include the
> tests in xenomai sources, then include them patched, or do not include them,
> and include the patch.
I cannot 100% follow here. There is one xenomai-specific test suite included,
which is written for xenomai specifically and the original FreeRTOS "demo".
The FreeRTOS "demo" is downloadable with and will be patched by the patches
that are checked in. This demo code might be checked in with patches applied
alternatively. Is it that what you were suggesting? Or did I simply not make
clear the difference between the "testsuite" and the "demo"?
Matthias
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Xenomai] FreeRTOS skin
2014-05-04 21:22 ` Matthias Schneider
@ 2014-05-05 7:24 ` Philippe Gerum
2014-05-17 14:40 ` Matthias Schneider
1 sibling, 0 replies; 21+ messages in thread
From: Philippe Gerum @ 2014-05-05 7:24 UTC (permalink / raw)
To: Matthias Schneider, Gilles Chanteperdrix, xenomai@xenomai.org
On 05/04/2014 11:22 PM, Matthias Schneider wrote:
> ----- Original Message -----
>
>> From: Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>
>> To: Matthias Schneider <ma30002000@yahoo.de>; "xenomai@xenomai.org" <xenomai@xenomai.org>
>> Cc:
>> Sent: Sunday, May 4, 2014 8:42 PM
>> Subject: Re: [Xenomai] FreeRTOS skin
>>
>> On 05/04/2014 06:59 PM, Matthias Schneider wrote:
>>> Hi all,
>>>
>>> please find enclosed a patch with a FreeRTOS skin for xenomai-forge I have
>>> been working on for some time. I would like to get some feedback and advice
>>> what still needs to be done to get it accepted in Xenomai. There is a set of
>>> unit tests included and the possibility to download the original FreeRTOS package
>>> in order to run most of its (platform independent) test suite. Until now I have
>>> been working under mercury only. Documentation is available in form of a README
>>> file in lib/freertos/README, which should also be a good starting point. I have
>>> not attached "configure" to the patch, so you will need to recreate the configure
>>> script first before actually running it. You can apply the patch via
>>
>>
>> Hi,
>>
>> I am not sure that checking whether a type is compatible with void *
>> will not suddenly avoid the assert check for any pointer type in:
>>
>> @@ -328,6 +328,7 @@ static inline int pshared_check(void *heap, void *addr)
>> ({
>> \
>> type handle; \
>> assert(__builtin_types_compatible_p(typeof(type), unsigned long) || \
>> + __builtin_types_compatible_p(typeof(type), void*) || \
>> __builtin_types_compatible_p(typeof(type), uintptr_t));
>> \
>> assert(ptr == NULL || __memchk(__main_heap, ptr)); \
>> handle = (type)ptr; \
>> @@ -337,6 +338,7 @@ static inline int pshared_check(void *heap, void *addr)
>> ({
>> \
>> type *ptr; \
>> assert(__builtin_types_compatible_p(typeof(handle), unsigned long) || \
>> + __builtin_types_compatible_p(typeof(handle), void*) || \
>> __builtin_types_compatible_p(typeof(handle), uintptr_t));
>> \
>> ptr = (type *)handle; \
>> ptr; \
>>
> I do agree with the argument; actually originally I had typedef'ed
> xQueueHandle, xTaskHandle and xSemaphorehandle as uintptr_t.
> However, when compiling original FreeRTOS applications like the
> "demo", I ran into many warnings (warning: comparison between
> pointer and integer) when comparing the handles to "NULL"
> like
>
> if (queueHandle != NULL) {}
>
> Now I see three possibilities:
> * stick with the void* and allow it in the check (admittedly
> greatly reducing its use)
> * change the application code
> * suppress warnings when compiling application code (not really
> my favorite)
>
> Originally the handles are tyepdef'ed to void* as well.
> Any ideas?
>
The point of this assertion is to make sure that your skin-defined object handle is wide enough to convey a native pointer directly, for the process-private configuration (with shared multi-processing enabled, this type would convey an offset instead).
There is no point in using a runtime assertion for C, we should be doing this instead:
diff --git a/include/copperplate/heapobj.h b/include/copperplate/heapobj.h
index 38deb89..6b5617c 100644
--- a/include/copperplate/heapobj.h
+++ b/include/copperplate/heapobj.h
@@ -324,21 +324,30 @@ static inline int pshared_check(void *heap, void *addr)
return 0;
}
+#ifdef __cplusplus
+#define __check_ref_width(__dst, __src) \
+ ({ \
+ assert(sizeof(__dst) >= sizeof(__src)); \
+ (typeof(__dst))__src; \
+ })
+#else
+#define __check_ref_width(__dst, __src) \
+ __builtin_choose_expr( \
+ sizeof(__dst) >= sizeof(__src), (typeof(__dst))__src, \
+ ((void)0))
+#endif
+
#define mainheap_ref(ptr, type) \
({ \
type handle; \
- assert(__builtin_types_compatible_p(typeof(type), unsigned long) || \
- __builtin_types_compatible_p(typeof(type), uintptr_t)); \
+ handle = __check_ref_width(handle, ptr); \
assert(ptr == NULL || __memchk(__main_heap, ptr)); \
- handle = (type)ptr; \
handle; \
})
#define mainheap_deref(handle, type) \
({ \
type *ptr; \
- assert(__builtin_types_compatible_p(typeof(handle), unsigned long) || \
- __builtin_types_compatible_p(typeof(handle), uintptr_t)); \
- ptr = (type *)handle; \
+ ptr = __check_ref_width(ptr, handle); \
ptr; \
})
--
Philippe.
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [Xenomai] FreeRTOS skin
2014-05-04 16:59 [Xenomai] FreeRTOS skin Matthias Schneider
2014-05-04 18:42 ` Gilles Chanteperdrix
@ 2014-05-05 10:33 ` Philippe Gerum
2014-05-05 13:37 ` Philippe Gerum
` (3 more replies)
1 sibling, 4 replies; 21+ messages in thread
From: Philippe Gerum @ 2014-05-05 10:33 UTC (permalink / raw)
To: Matthias Schneider, xenomai@xenomai.org
On 05/04/2014 06:59 PM, Matthias Schneider wrote:
> Hi all,
>
> please find enclosed a patch with a FreeRTOS skin for xenomai-forge I have
> been working on for some time. I would like to get some feedback and advice
> what still needs to be done to get it accepted in Xenomai. There is a set of
> unit tests included and the possibility to download the original FreeRTOS package
> in order to run most of its (platform independent) test suite. Until now I have
> been working under mercury only. Documentation is available in form of a README
> file in lib/freertos/README, which should also be a good starting point.
Ok, thanks for this. Let's address issues gradually, starting with the
task module.
I'd suggest to revisit the following mechanisms to get our feet wet:
vTaskStartScheduler()/vTaskEndScheduler() and
vTaskSuspendAll()/vTaskResumeAll().
- synchronizing on scheduler start/stop events can be made simpler, by
waiting on a barrier after threadobj_wait_start() has returned in the
task trampoline, meanwhile starting all tasks copperplate-wise at
creation time via threadobj_start(). Such additional barrier should be a
condition variable protected by your current scheduler.lock mutex,
signaled by vTaskStartScheduler(). Tasks would have to check for the
scheduler state before breaking the wait loop.
- assuming that threadobj_cancel() already waits for the canceled thread
to finalize, you should only need to change the scheduler object state
in vTaskEndScheduler() prior to cancelling all tasks. You should not
need the extra syncobj.
- vTaskSuspendAll()/vTaskResumeAll() maintain useless status flags.
Copperplate provides __THREAD_S_SUSPENDED in the core status of threads
for the very same purpose.
The other set of issues is all about locking is managed. A couple of hints:
- vPortEnterCritical()/vPortExitCritical() can't be emulated since we
can't mask IRQs in userland (and we certainly don't want to even try
doing so). This would be a RTDM driver's business in the Xenomai model.
Looking at the FreeRTOS doc, the closest approximation would be
threadobj_sched_lock() in userland, but since hardware drivers should
move to kernel space over RTDM, I'm unsure emulating these calls has any
benefit in our context.
- threadobj_sched_lock() does not prevent the caller from scheduling
out, it only stops involuntary preemption when running non-blocking
code. Typically, locking a mutex is potentially blocking code, so the
guarantee disappears in that case. IIUC, the current code assumes more
than this. Moreover, issuing a sleeping call voluntarily when holding
this lock is logically wrong, even if Xenomai won't jump over the window
doing so, unlike many RTOS vTaskStartScheduler()).
- the read/write_lock_nocancel() form is reserved for protecting
sections which are known not to traverse cancellation points, as defined
by POSIX
(http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html).
This is about self-documentation of the code, and optimizing execution
by omitting costly management of cleanup blocks when it is deemed safe
to do so.
- CANCEL_DEFER() / CANCEL_RESTORE() should protect sections against
asynchronous cancellation, we typically do this before invoking the
copperplate layer, so that we may assume that pthread_cancel() won't be
a problem when running inner code, provided we have been careful about
handling read/write lock cleanups. These macros work by disabling
asynchronous cancellation for the current thread when
--enable-async-cancel was given at build time. Otherwise, this part is a
nop.
- Scheduler.queued_task, .state and .num_tasks all seem logically
related. So .num_tasks should be updated holding Scheduler.lock, instead
of using an atomic type. We'd need to issue smp_rmb() prior to reading
that counter locklessly.
HTH,
--
Philippe.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Xenomai] FreeRTOS skin
2014-05-05 10:33 ` Philippe Gerum
@ 2014-05-05 13:37 ` Philippe Gerum
2014-05-06 7:09 ` Matthias Schneider
2014-05-05 14:03 ` Gilles Chanteperdrix
` (2 subsequent siblings)
3 siblings, 1 reply; 21+ messages in thread
From: Philippe Gerum @ 2014-05-05 13:37 UTC (permalink / raw)
To: Matthias Schneider, xenomai@xenomai.org
On 05/05/2014 12:33 PM, Philippe Gerum wrote:
> On 05/04/2014 06:59 PM, Matthias Schneider wrote:
>> Hi all,
>>
>> please find enclosed a patch with a FreeRTOS skin for xenomai-forge I
>> have
>> been working on for some time. I would like to get some feedback and
>> advice
>> what still needs to be done to get it accepted in Xenomai. There is a
>> set of
>> unit tests included and the possibility to download the original
>> FreeRTOS package
>> in order to run most of its (platform independent) test suite. Until
>> now I have
>> been working under mercury only. Documentation is available in form of
>> a README
>> file in lib/freertos/README, which should also be a good starting point.
>
> Ok, thanks for this. Let's address issues gradually, starting with the
> task module.
>
In addition to the above, there are a few coding style items:
- Please always take the fastest possible path when exiting on error,
so that we don't have to cripple the normal processing following the
failure point with error-specific checks. e.g. what is done with the
"task" variable in vTaskStartScheduler(), within the thread
cancellation loop, ends up being convoluted and confusing, compared
to unwinding and leaving the routine immediately after the error is
detected.
- (void)function_call() is useless visual pollution and tells nothing
about the only thing that matters to the reader: were you right in
omitting the check? Instead, tagging the called routine with the
((warn_unused_result)) attribute when problems may likely arise from
not checking the return value, seems a better way to detect
potential bugs at build time, which would cause the (void) cast to
be ignored when checking the call sites anyway.
- Prefer C-style comments over C++-style ones.
--
Philippe.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Xenomai] FreeRTOS skin
2014-05-05 10:33 ` Philippe Gerum
2014-05-05 13:37 ` Philippe Gerum
@ 2014-05-05 14:03 ` Gilles Chanteperdrix
2014-05-05 14:13 ` Philippe Gerum
2014-05-06 17:19 ` Matthias Schneider
2014-05-18 18:30 ` Matthias Schneider
3 siblings, 1 reply; 21+ messages in thread
From: Gilles Chanteperdrix @ 2014-05-05 14:03 UTC (permalink / raw)
To: Philippe Gerum, Matthias Schneider, xenomai@xenomai.org
On 05/05/2014 12:33 PM, Philippe Gerum wrote:
> - vTaskSuspendAll()/vTaskResumeAll() maintain useless status flags.
> Copperplate provides __THREAD_S_SUSPENDED in the core status of threads
> for the very same purpose.
I believe in FreeRTOS vTaskSuspendAll/vTaskResumeAll is more like a task
lock mechanism than a service suspending/resuming all tasks for real. Of
course this only provides mutual exclusion on UP.
--
Gilles.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Xenomai] FreeRTOS skin
2014-05-05 14:03 ` Gilles Chanteperdrix
@ 2014-05-05 14:13 ` Philippe Gerum
0 siblings, 0 replies; 21+ messages in thread
From: Philippe Gerum @ 2014-05-05 14:13 UTC (permalink / raw)
To: Gilles Chanteperdrix, Matthias Schneider, xenomai@xenomai.org
On 05/05/2014 04:03 PM, Gilles Chanteperdrix wrote:
> On 05/05/2014 12:33 PM, Philippe Gerum wrote:
>> - vTaskSuspendAll()/vTaskResumeAll() maintain useless status flags.
>> Copperplate provides __THREAD_S_SUSPENDED in the core status of threads
>> for the very same purpose.
>
> I believe in FreeRTOS vTaskSuspendAll/vTaskResumeAll is more like a task
> lock mechanism than a service suspending/resuming all tasks for real. Of
> course this only provides mutual exclusion on UP.
>
>
Definitely, this is threadobj_sched_lock() in all its glory. A bit of a
misnomer. So the current implementation could be simplified a lot it seems.
--
Philippe.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Xenomai] FreeRTOS skin
2014-05-05 13:37 ` Philippe Gerum
@ 2014-05-06 7:09 ` Matthias Schneider
2014-05-06 7:46 ` Philippe Gerum
0 siblings, 1 reply; 21+ messages in thread
From: Matthias Schneider @ 2014-05-06 7:09 UTC (permalink / raw)
To: Philippe Gerum, xenomai@xenomai.org
----- Original Message -----
> From: Philippe Gerum <rpm@xenomai.org>
> To: Matthias Schneider <ma30002000@yahoo.de>; "xenomai@xenomai.org" <xenomai@xenomai.org>
> Cc:
> Sent: Monday, May 5, 2014 3:37 PM
> Subject: Re: [Xenomai] FreeRTOS skin
>
> On 05/05/2014 12:33 PM, Philippe Gerum wrote:
>> On 05/04/2014 06:59 PM, Matthias Schneider wrote:
>>> Hi all,
>>>
>>> please find enclosed a patch with a FreeRTOS skin for xenomai-forge I
>>> have
>>> been working on for some time. I would like to get some feedback and
>>> advice
>>> what still needs to be done to get it accepted in Xenomai. There is a
>>> set of
>>> unit tests included and the possibility to download the original
>>> FreeRTOS package
>>> in order to run most of its (platform independent) test suite. Until
>>> now I have
>>> been working under mercury only. Documentation is available in form of
>>> a README
>>> file in lib/freertos/README, which should also be a good starting
> point.
>>
>> Ok, thanks for this. Let's address issues gradually, starting with the
>> task module.
>>
>
> In addition to the above, there are a few coding style items:
>
> - Please always take the fastest possible path when exiting on error,
> so that we don't have to cripple the normal processing following the
> failure point with error-specific checks. e.g. what is done with the
> "task" variable in vTaskStartScheduler(), within the thread
> cancellation loop, ends up being convoluted and confusing, compared
> to unwinding and leaving the routine immediately after the error is
> detected.
I will review the code and simplify occurrences of the mentioned pattern.
However I do not see this pattern in this particular code fragment, since it basically does the following:
* take the first entry of the task list
* check if the task object can be locked
* unlock the scheduler lock
* if it was possible to lock the task, cancel it
* else wait 1ms and try to lock it again
No error condition leads to leaving this loop. I do agree however, that the
code is convoluted, mainly due to the erroneous-looking nested locks, one
for protecting freertos_task_list and one locking the threadobj. The list should be locked while accessing it, while holding it when cancelling the threadobj will lead to deadlocks (task_finalizer takes freertos_scheduler.lock).
> - (void)function_call() is useless visual pollution and tells nothing
> about the only thing that matters to the reader: were you right in
> omitting the check? Instead, tagging the called routine with the
> ((warn_unused_result)) attribute when problems may likely arise from
> not checking the return value, seems a better way to detect
> potential bugs at build time, which would cause the (void) cast to
> be ignored when checking the call sites anyway.
Removed the casts.
> - Prefer C-style comments over C++-style ones.
Changed the comments.
>
>
> --
> Philippe.
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Xenomai] FreeRTOS skin
2014-05-06 7:09 ` Matthias Schneider
@ 2014-05-06 7:46 ` Philippe Gerum
2014-05-06 7:54 ` Philippe Gerum
2014-05-06 16:50 ` Matthias Schneider
0 siblings, 2 replies; 21+ messages in thread
From: Philippe Gerum @ 2014-05-06 7:46 UTC (permalink / raw)
To: Matthias Schneider, xenomai@xenomai.org
On 05/06/2014 09:09 AM, Matthias Schneider wrote:
> ----- Original Message -----
>> From: Philippe Gerum <rpm@xenomai.org>
>> To: Matthias Schneider <ma30002000@yahoo.de>; "xenomai@xenomai.org" <xenomai@xenomai.org>
>> Cc:
>> Sent: Monday, May 5, 2014 3:37 PM
>> Subject: Re: [Xenomai] FreeRTOS skin
>>
>> On 05/05/2014 12:33 PM, Philippe Gerum wrote:
>>> On 05/04/2014 06:59 PM, Matthias Schneider wrote:
>>>> Hi all,
>>>>
>>>> please find enclosed a patch with a FreeRTOS skin for xenomai-forge I
>>>> have
>>>> been working on for some time. I would like to get some feedback and
>>>> advice
>>>> what still needs to be done to get it accepted in Xenomai. There is a
>>>> set of
>>>> unit tests included and the possibility to download the original
>>>> FreeRTOS package
>>>> in order to run most of its (platform independent) test suite. Until
>>>> now I have
>>>> been working under mercury only. Documentation is available in form of
>>>> a README
>>>> file in lib/freertos/README, which should also be a good starting
>> point.
>>>
>>> Ok, thanks for this. Let's address issues gradually, starting with the
>>> task module.
>>>
>>
>> In addition to the above, there are a few coding style items:
>>
>> - Please always take the fastest possible path when exiting on error,
>> so that we don't have to cripple the normal processing following the
>> failure point with error-specific checks. e.g. what is done with the
>> "task" variable in vTaskStartScheduler(), within the thread
>> cancellation loop, ends up being convoluted and confusing, compared
>> to unwinding and leaving the routine immediately after the error is
>> detected.
>
>
> I will review the code and simplify occurrences of the mentioned pattern.
> However I do not see this pattern in this particular code fragment, since it basically does the following:
>
> * take the first entry of the task list
The first check for list emptiness looks racy, as it is not covered by
the scheduler.lock.
> * check if the task object can be locked
> * unlock the scheduler lock
> * if it was possible to lock the task, cancel it
> * else wait 1ms and try to lock it again
If you found it in your task queue but can't lock it, then call Houston
because we have a problem: the task finalizer where this task is dropped
from the list runs prior to deleting the lock. However, testing for the
magic word on success is indeed required in the current implementation,
since the thread lock is dropped shortly prior to canceling the thread
in copperplate.
You could use pvlist_for_each_entry_safe() for iterating over the task
queue.
>
> No error condition leads to leaving this loop. I do agree however, that the
> code is convoluted, mainly due to the erroneous-looking nested locks, one
> for protecting freertos_task_list and one locking the threadobj. The list should be locked while accessing it, while holding it when cancelling the threadobj will lead to deadlocks (task_finalizer takes freertos_scheduler.lock).
>
Setting task to NULL upon locking error, only for the purpose of
avoiding the magic check in the normal code flow is the issue I mentioned:
if (task && threadobj_lock(&task->thobj) == -EINVAL)
task = NULL;
if (task && threadobj_get_magic(&task->thobj) != task_magic) {
threadobj_unlock(&task->thobj);
task = NULL;
}
>
>> - (void)function_call() is useless visual pollution and tells nothing
>> about the only thing that matters to the reader: were you right in
>> omitting the check? Instead, tagging the called routine with the
>> ((warn_unused_result)) attribute when problems may likely arise from
>> not checking the return value, seems a better way to detect
>> potential bugs at build time, which would cause the (void) cast to
>> be ignored when checking the call sites anyway.
> Removed the casts.
>
Thanks, I'll add some warn_unused_result tags to some routines from the
copperplate layer. syncobj_wait* services come to mind, since these may
return -EIDRM or -EINTR, which are situations which have to influence
the code flow when received.
--
Philippe.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Xenomai] FreeRTOS skin
2014-05-06 7:46 ` Philippe Gerum
@ 2014-05-06 7:54 ` Philippe Gerum
2014-05-06 16:50 ` Matthias Schneider
1 sibling, 0 replies; 21+ messages in thread
From: Philippe Gerum @ 2014-05-06 7:54 UTC (permalink / raw)
To: Matthias Schneider, xenomai@xenomai.org
On 05/06/2014 09:46 AM, Philippe Gerum wrote:
> On 05/06/2014 09:09 AM, Matthias Schneider wrote:
>> ----- Original Message -----
>>> From: Philippe Gerum <rpm@xenomai.org>
>>> To: Matthias Schneider <ma30002000@yahoo.de>; "xenomai@xenomai.org"
>>> <xenomai@xenomai.org>
>>> Cc:
>>> Sent: Monday, May 5, 2014 3:37 PM
>>> Subject: Re: [Xenomai] FreeRTOS skin
>>>
>>> On 05/05/2014 12:33 PM, Philippe Gerum wrote:
>>>> On 05/04/2014 06:59 PM, Matthias Schneider wrote:
>>>>> Hi all,
>>>>>
>>>>> please find enclosed a patch with a FreeRTOS skin for
>>>>> xenomai-forge I
>>>>> have
>>>>> been working on for some time. I would like to get some
>>>>> feedback and
>>>>> advice
>>>>> what still needs to be done to get it accepted in Xenomai. There
>>>>> is a
>>>>> set of
>>>>> unit tests included and the possibility to download the original
>>>>> FreeRTOS package
>>>>> in order to run most of its (platform independent) test suite.
>>>>> Until
>>>>> now I have
>>>>> been working under mercury only. Documentation is available in
>>>>> form of
>>>>> a README
>>>>> file in lib/freertos/README, which should also be a good starting
>>> point.
>>>>
>>>> Ok, thanks for this. Let's address issues gradually, starting
>>>> with the
>>>> task module.
>>>>
>>>
>>> In addition to the above, there are a few coding style items:
>>>
>>> - Please always take the fastest possible path when exiting on error,
>>> so that we don't have to cripple the normal processing following the
>>> failure point with error-specific checks. e.g. what is done with the
>>> "task" variable in vTaskStartScheduler(), within the thread
>>> cancellation loop, ends up being convoluted and confusing, compared
>>> to unwinding and leaving the routine immediately after the error is
>>> detected.
>>
>>
>> I will review the code and simplify occurrences of the mentioned pattern.
>> However I do not see this pattern in this particular code fragment,
>> since it basically does the following:
>>
>> * take the first entry of the task list
>
> The first check for list emptiness looks racy, as it is not covered by
> the scheduler.lock.
>
>> * check if the task object can be locked
>> * unlock the scheduler lock
>> * if it was possible to lock the task, cancel it
>> * else wait 1ms and try to lock it again
>
> If you found it in your task queue but can't lock it, then call Houston
> because we have a problem: the task finalizer where this task is dropped
> from the list runs prior to deleting the lock.
No, I'm wrong. There is still a race which could allow that. So we need
both checks.
--
Philippe.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Xenomai] FreeRTOS skin
2014-05-06 7:46 ` Philippe Gerum
2014-05-06 7:54 ` Philippe Gerum
@ 2014-05-06 16:50 ` Matthias Schneider
2014-05-17 14:56 ` Matthias Schneider
1 sibling, 1 reply; 21+ messages in thread
From: Matthias Schneider @ 2014-05-06 16:50 UTC (permalink / raw)
To: Philippe Gerum, xenomai@xenomai.org
> From: Philippe Gerum <rpm@xenomai.org>
> On 05/06/2014 09:09 AM, Matthias Schneider wrote:
>>> On 05/05/2014 12:33 PM, Philippe Gerum wrote:
>>>> On 05/04/2014 06:59 PM, Matthias Schneider wrote:
>>>>> Hi all,
>>>>>
>>>>> please find enclosed a patch with a FreeRTOS skin for xenomai-forge I
>>>>> have been working on for some time.
[...]
>>>>
>>>> Ok, thanks for this. Let's address issues gradually, starting with the
>>>> task module.
>>>>
>>>
>>> In addition to the above, there are a few coding style items:
>>>
>>> - Please always take the fastest possible path when exiting on error,
>>> so that we don't have to cripple the normal processing following the
>>> failure point with error-specific checks. e.g. what is done with the
>>> "task" variable in vTaskStartScheduler(), within the thread
>>> cancellation loop, ends up being convoluted and confusing, compared
>>> to unwinding and leaving the routine immediately after the error is
>>> detected.
>>
>>
>> I will review the code and simplify occurrences of the mentioned pattern.
>> However I do not see this pattern in this particular code fragment, since
> it basically does the following:
>>
>> * take the first entry of the task list
>
> The first check for list emptiness looks racy, as it is not covered by
> the scheduler.lock.
True. See below.
>> * check if the task object can be locked
>> * unlock the scheduler lock
>> * if it was possible to lock the task, cancel it
>> * else wait 1ms and try to lock it again
>
> If you found it in your task queue but can't lock it, then call Houston
> because we have a problem: the task finalizer where this task is dropped
> from the list runs prior to deleting the lock. However, testing for the
> magic word on success is indeed required in the current implementation,
> since the thread lock is dropped shortly prior to canceling the thread
> in copperplate.
>
> You could use pvlist_for_each_entry_safe() for iterating over the task
> queue.
>
>>
>> No error condition leads to leaving this loop. I do agree however, that the
>> code is convoluted, mainly due to the erroneous-looking nested locks, one
>> for protecting freertos_task_list and one locking the threadobj. The list
> should be locked while accessing it, while holding it when cancelling the
> threadobj will lead to deadlocks (task_finalizer takes freertos_scheduler.lock).
>>
>
> Setting task to NULL upon locking error, only for the purpose of
> avoiding the magic check in the normal code flow is the issue I mentioned:
>
> if (task && threadobj_lock(&task->thobj) == -EINVAL)
> task = NULL;
>
> if (task && threadobj_get_magic(&task->thobj) !=
> task_magic) {
> threadobj_unlock(&task->thobj);
> task = NULL;
> }
>
[...]
Ok let's simplify the code (and add the missing lock):
write_lock_nocancel(&freertos_scheduler.lock);
freertos_scheduler.state = taskSCHEDULER_NOT_STARTED;
/* cancel all tasks in list */
while (!pvlist_empty(&freertos_task_list)) {
task = pvlist_first_entry(&freertos_task_list, struct freertos_task, next);
if (threadobj_lock(&task->thobj) != -EINVAL) {
if (threadobj_get_magic(&task->thobj) == task_magic) {
/* need to leave freertos_scheduler.lock since it is
taken in task_finalizer while we block in
threadobj_cancel */
write_unlock(&freertos_scheduler.lock);
threadobj_cancel(&task->thobj);
write_lock_nocancel(&freertos_scheduler.lock);
continue;
}
threadobj_unlock(&task->thobj);
}
/* Need to release the lock for a while since a task in deletion
may need it to unregister itself from freertos_task_list */
write_unlock(&freertos_scheduler.lock);
struct timespec rqt;
clockobj_ticks_to_timeout(&freertos_clock,
0.001 * xGetTicksPerSecond(),
&rqt);
threadobj_sleep(&rqt);
write_lock_nocancel(&freertos_scheduler.lock);
}
write_unlock(&freertos_scheduler.lock);
I had used pvlist_for_each_entry_safe() originally, but due to the possibility
having to access a single task multiple times, I ended up with two nested loops.
> --
> Philippe.
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Xenomai] FreeRTOS skin
2014-05-05 10:33 ` Philippe Gerum
2014-05-05 13:37 ` Philippe Gerum
2014-05-05 14:03 ` Gilles Chanteperdrix
@ 2014-05-06 17:19 ` Matthias Schneider
2014-05-06 17:47 ` Philippe Gerum
2014-05-18 18:30 ` Matthias Schneider
3 siblings, 1 reply; 21+ messages in thread
From: Matthias Schneider @ 2014-05-06 17:19 UTC (permalink / raw)
To: Philippe Gerum, xenomai@xenomai.org
----- Original Message -----
> From: Philippe Gerum <rpm@xenomai.org>
> To: Matthias Schneider <ma30002000@yahoo.de>; "xenomai@xenomai.org" <xenomai@xenomai.org>
> Cc:
> Sent: Monday, May 5, 2014 12:33 PM
> Subject: Re: [Xenomai] FreeRTOS skin
>
> On 05/04/2014 06:59 PM, Matthias Schneider wrote:
>
>> Hi all,
>>
>> please find enclosed a patch with a FreeRTOS skin for xenomai-forge I have
>> been working on for some time. I would like to get some feedback and advice
>> what still needs to be done to get it accepted in Xenomai. There is a set of
>> unit tests included and the possibility to download the original FreeRTOS package
>> in order to run most of its (platform independent) test suite. Until now I have
>> been working under mercury only. Documentation is available in form of a README
>> file in lib/freertos/README, which should also be a good starting point.
>
> Ok, thanks for this. Let's address issues gradually, starting with the task module.
I will try to address some of the mentioned issues now, the rest later:
> I'd suggest to revisit the following mechanisms to get our feet wet:
> vTaskStartScheduler()/vTaskEndScheduler() and
> vTaskSuspendAll()/vTaskResumeAll().
>
> - synchronizing on scheduler start/stop events can be made simpler, by
> waiting on a barrier after threadobj_wait_start() has returned in the
> task trampoline, meanwhile starting all tasks copperplate-wise at
> creation time via threadobj_start(). Such additional barrier should be a
> condition variable protected by your current scheduler.lock mutex,
> signaled by vTaskStartScheduler(). Tasks would have to check for the
> scheduler state before breaking the wait loop.
>
> - assuming that threadobj_cancel() already waits for the canceled thread
> to finalize, you should only need to change the scheduler object state
> in vTaskEndScheduler() prior to cancelling all tasks. You should not
> need the extra syncobj.
Are you referring to freertos_scheduler.sem? It is used to blocke the
main thread while the "scheduer" is running. Even when moving the task
cancellation loop to inside the vTaskEndScheduler(), vTaskStartScheduler()
would still need to block until vTaskEndScheduler() is a
> - vTaskSuspendAll()/vTaskResumeAll() maintain useless status flags.
> Copperplate provides __THREAD_S_SUSPENDED in the core status of threads
> for the very same purpose.
This is not entirely correct. Consider the following case (part of the demo
actually):
vTaskSuspendAll();
vTaskSuspend(th1);
vTaskResumeAll();
This is supposed to leave th1 suspended after vTaskResumeAll(). This
information needs to be stored somewhere. After vTaskSuspendAll(), all
except the current thread have __THREAD_S_SUSPENDED set, so another way to
store this informaion is needed. I have also experimented modelling these
functions using threadobj_sched_lock() & co., however, even on UP machines
the following code would not behave as supposed:
vTaskSuspendAll();
vTaskDelay(xGetTicksPerSecond() * 0.01);
vTaskResumeAll();
Obviously, during vTaskDelay() other tasks of lower than "sched" prio may
be executed.
> The other set of issues is all about locking is managed. A couple of hints:
>
> - vPortEnterCritical()/vPortExitCritical() can't be emulated since we
> can't mask IRQs in userland (and we certainly don't want to even try
> doing so). This would be a RTDM driver's business in the Xenomai model.
> Looking at the FreeRTOS doc, the closest approximation would be
> threadobj_sched_lock() in userland, but since hardware drivers should
> move to kernel space over RTDM, I'm unsure emulating these calls has any
> benefit in our context.
Correct. I though I had seen use of it in the plateform-independent demo
previously, but apparently I remember incorrectly. Defining them as empty
functions thus.
>
> - threadobj_sched_lock() does not prevent the caller from scheduling
> out, it only stops involuntary preemption when running non-blocking
> code. Typically, locking a mutex is potentially blocking code, so the
> guarantee disappears in that case. IIUC, the current code assumes more
> than this. Moreover, issuing a sleeping call voluntarily when holding
> this lock is logically wrong, even if Xenomai won't jump over the window
> doing so, unlike many RTOS vTaskStartScheduler()).
>
> - the read/write_lock_nocancel() form is reserved for protecting
> sections which are known not to traverse cancellation points, as defined
> by POSIX
> (http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html).
> This is about self-documentation of the code, and optimizing execution
> by omitting costly management of cleanup blocks when it is deemed safe
> to do so.
>
> - CANCEL_DEFER() / CANCEL_RESTORE() should protect sections against
> asynchronous cancellation, we typically do this before invoking the
> copperplate layer, so that we may assume that pthread_cancel() won't be
> a problem when running inner code, provided we have been careful about
> handling read/write lock cleanups. These macros work by disabling
> asynchronous cancellation for the current thread when
> --enable-async-cancel was given at build time. Otherwise, this part is a
> nop.
>
> - Scheduler.queued_task, .state and .num_tasks all seem logically
> related. So .num_tasks should be updated holding Scheduler.lock, instead
> of using an atomic type. We'd need to issue smp_rmb() prior to reading
> that counter locklessly.
>
> HTH,
>
> --
> Philippe.
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Xenomai] FreeRTOS skin
2014-05-06 17:19 ` Matthias Schneider
@ 2014-05-06 17:47 ` Philippe Gerum
2014-05-06 19:46 ` Matthias Schneider
0 siblings, 1 reply; 21+ messages in thread
From: Philippe Gerum @ 2014-05-06 17:47 UTC (permalink / raw)
To: Matthias Schneider, xenomai@xenomai.org
On 05/06/2014 07:19 PM, Matthias Schneider wrote:
>
> Are you referring to freertos_scheduler.sem? It is used to blocke the
> main thread while the "scheduer" is running. Even when moving the task
> cancellation loop to inside the vTaskEndScheduler(), vTaskStartScheduler()
> would still need to block until vTaskEndScheduler() is a
>
I mean you don't need a syncobj. This is overly complex for the purpose,
you can use a sem_t. syncobj implements extended semantics we commonly
find in RTOS, which are not available with regular POSIX ipc. But in
this case, we don't need them: we just need to wait for a pulse, once.
>> - vTaskSuspendAll()/vTaskResumeAll() maintain useless status flags.
>> Copperplate provides __THREAD_S_SUSPENDED in the core status of threads
>> for the very same purpose.
>
> This is not entirely correct. Consider the following case (part of the demo
> actually):
>
> vTaskSuspendAll();
> vTaskSuspend(th1);
> vTaskResumeAll();
>
> This is supposed to leave th1 suspended after vTaskResumeAll(). This
> information needs to be stored somewhere. After vTaskSuspendAll(), all
> except the current thread have __THREAD_S_SUSPENDED set, so another way to
> store this informaion is needed. I have also experimented modelling these
> functions using threadobj_sched_lock() & co., however, even on UP machines
> the following code would not behave as supposed:
>
> vTaskSuspendAll();
> vTaskDelay(xGetTicksPerSecond() * 0.01);
> vTaskResumeAll();
>
> Obviously, during vTaskDelay() other tasks of lower than "sched" prio may
> be executed.
vTaskSuspendAll() very much looks like plain scheduler lock, preventing
the caller from scheduling out on preemption. If so, then the whole
issue disappears, there would not be any cumulative blocking states.
>
>> The other set of issues is all about locking is managed. A couple of hints:
>>
>> - vPortEnterCritical()/vPortExitCritical() can't be emulated since we
>> can't mask IRQs in userland (and we certainly don't want to even try
>> doing so). This would be a RTDM driver's business in the Xenomai model.
>> Looking at the FreeRTOS doc, the closest approximation would be
>> threadobj_sched_lock() in userland, but since hardware drivers should
>> move to kernel space over RTDM, I'm unsure emulating these calls has any
>> benefit in our context.
>
> Correct. I though I had seen use of it in the plateform-independent demo
> previously, but apparently I remember incorrectly. Defining them as empty
> functions thus.
>
I would rather not define them, to make sure the user knows about the
issue when the compiler complains about it. Silently ignoring a hard
critical section is unlikely to help.
--
Philippe.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Xenomai] FreeRTOS skin
2014-05-06 17:47 ` Philippe Gerum
@ 2014-05-06 19:46 ` Matthias Schneider
0 siblings, 0 replies; 21+ messages in thread
From: Matthias Schneider @ 2014-05-06 19:46 UTC (permalink / raw)
To: Philippe Gerum, xenomai@xenomai.org
----- Original Message -----
> From: Philippe Gerum <rpm@xenomai.org>
> To: Matthias Schneider <ma30002000@yahoo.de>; "xenomai@xenomai.org" <xenomai@xenomai.org>
> Cc:
> Sent: Tuesday, May 6, 2014 7:47 PM
> Subject: Re: [Xenomai] FreeRTOS skin
>
> On 05/06/2014 07:19 PM, Matthias Schneider wrote:
>>
>> Are you referring to freertos_scheduler.sem? It is used to blocke the
>> main thread while the "scheduer" is running. Even when moving the
> task
>> cancellation loop to inside the vTaskEndScheduler(), vTaskStartScheduler()
>> would still need to block until vTaskEndScheduler() is a
>>
>
> I mean you don't need a syncobj. This is overly complex for the purpose,
> you can use a sem_t. syncobj implements extended semantics we commonly
> find in RTOS, which are not available with regular POSIX ipc. But in
> this case, we don't need them: we just need to wait for a pulse, once.
Ok, got it. Now the last question concerning this, should it be a
_RT(sem_init) or _STD(sem_init)? Does it matter in this case?
>>> - vTaskSuspendAll()/vTaskResumeAll() maintain useless status flags.
>>> Copperplate provides __THREAD_S_SUSPENDED in the core status of threads
>>> for the very same purpose.
>>
>> This is not entirely correct. Consider the following case (part of the demo
>> actually):
>>
>> vTaskSuspendAll();
>> vTaskSuspend(th1);
>> vTaskResumeAll();
>>
>> This is supposed to leave th1 suspended after vTaskResumeAll(). This
>> information needs to be stored somewhere. After vTaskSuspendAll(), all
>> except the current thread have __THREAD_S_SUSPENDED set, so another way to
>> store this informaion is needed. I have also experimented modelling these
>> functions using threadobj_sched_lock() & co., however, even on UP machines
>> the following code would not behave as supposed:
>>
>> vTaskSuspendAll();
>> vTaskDelay(xGetTicksPerSecond() * 0.01);
>> vTaskResumeAll();
>>
>> Obviously, during vTaskDelay() other tasks of lower than "sched" prio may
>> be executed.
>
> vTaskSuspendAll() very much looks like plain scheduler lock, preventing
> the caller from scheduling out on preemption. If so, then the whole
> issue disappears, there would not be any cumulative blocking states.
So the recommendation would be to go for the threadobj_sched_lock()
approach? But how can I address the mentioned issue of being scheduled
out when waiting? It would make a lot of things a lot easier, so much
for sure...
>>> The other set of issues is all about locking is managed. A couple of hints:
>>>
>>> - vPortEnterCritical()/vPortExitCritical() can't be emulated since we
>>> can't mask IRQs in userland (and we certainly don't want to even try
>>> doing so). This would be a RTDM driver's business in the Xenomai model.
>>> Looking at the FreeRTOS doc, the closest approximation would be
>>> threadobj_sched_lock() in userland, but since hardware drivers should
>>> move to kernel space over RTDM, I'm unsure emulating these calls has any
>>> benefit in our context.
>>
>> Correct. I though I had seen use of it in the plateform-independent demo
>> previously, but apparently I remember incorrectly. Defining them as empty
>> functions thus.
>>
>
> I would rather not define them, to make sure the user knows about the
> issue when the compiler complains about it. Silently ignoring a hard
> critical section is unlikely to help.
The platform-independent demo uses them a lot, although it does not
deal with interrupts at all.. If I remove them, I will need to patch
the demo, probably to the point where checking in the whole patched
demo will make more sense than adding more and more patch files.
Or maybe it should be something like threadobj_sched_lock() instead?
>
> --
> Philippe.
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Xenomai] FreeRTOS skin
2014-05-04 21:22 ` Matthias Schneider
2014-05-05 7:24 ` Philippe Gerum
@ 2014-05-17 14:40 ` Matthias Schneider
1 sibling, 0 replies; 21+ messages in thread
From: Matthias Schneider @ 2014-05-17 14:40 UTC (permalink / raw)
To: xenomai@xenomai.org
> From: Matthias Schneider <ma30002000@yahoo.de>
>> From: Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>
>> On 05/04/2014 06:59 PM, Matthias Schneider wrote:
>>> Hi all,
>>>
>>> please find enclosed a patch with a FreeRTOS skin for xenomai-forge I have
>>> been working on for some time. I would like to get some feedback and advice
>>> what still needs to be done to get it accepted in Xenomai.
[...]
I have removed all already addressed items (most of them) raised by Gilles. I
will publish an updated patch soon. However, the following points are still
open:
>> I believe there is an error in these macros definition:
>> This one looks strange:
>> +#define portNOP() __asm__ __volatile__ ("nop");
>>
>> If you do not care whether portNOP is a barrier you can drop the "volatile"
>> otherwise you should add "memory" as clobber.
>
> The original FreeRTOS implementation is "just" volatile (actually it is
> defined exactly the same way as in my header file), so it is a little
> difficult to guess the original authors' motives. Since I do not have any
> sample code that makes use of this macro, I am not sure of the implications
> on existing source code when changing it, independent from removing the volatile
> or adding the clobbering.
Not sure how to go on here, I propose to leave it as it is.
>> +#define xSemaphoreAltGive(xSemaphore) xSemaphoreGive(xMutex)
>> +
>> +#define xSemaphoreGiveFromISR(xSemaphore, pxHigherPriorityTaskWoken) \
>> + xSemaphoreGive(xMutex)
>> +
>>
>> About the testsuite: does it really make sense to include both the unpatched
>> testsuite and xenomai-specific patches? I mean if you want to include the
>> tests in xenomai sources, then include them patched, or do not include them,
>> and include the patch.
>
> I cannot 100% follow here. There is one xenomai-specific test suite included,
> which is written for xenomai specifically and the original FreeRTOS "demo".
> The FreeRTOS "demo" is downloadable with and will be patched by the
> patches
> that are checked in. This demo code might be checked in with patches applied
> alternatively. Is it that what you were suggesting? Or did I simply not make
> clear the difference between the "testsuite" and the "demo"?
Anything else I can do to clarify?
Matthias
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Xenomai] FreeRTOS skin
2014-05-06 16:50 ` Matthias Schneider
@ 2014-05-17 14:56 ` Matthias Schneider
0 siblings, 0 replies; 21+ messages in thread
From: Matthias Schneider @ 2014-05-17 14:56 UTC (permalink / raw)
To: Matthias Schneider, Philippe Gerum, xenomai@xenomai.org
----- Original Message -----
> From: Matthias Schneider <ma30002000@yahoo.de>
> To: Philippe Gerum <rpm@xenomai.org>; "xenomai@xenomai.org" <xenomai@xenomai.org>
> Cc:
> Sent: Tuesday, May 6, 2014 6:50 PM
> Subject: Re: [Xenomai] FreeRTOS skin
>
>> From: Philippe Gerum <rpm@xenomai.org>
>> On 05/06/2014 09:09 AM, Matthias Schneider wrote:
>>>> On 05/05/2014 12:33 PM, Philippe Gerum wrote:
>>>> In addition to the above, there are a few coding style items:
>>>> - Please always take the fastest possible path when exiting on error,
>>>> so that we don't have to cripple the normal processing following the
>>>> failure point with error-specific checks. e.g. what is done with the
>>>> "task" variable in vTaskStartScheduler(), within the thread
>>>> cancellation loop, ends up being convoluted and confusing, compared
>>>> to unwinding and leaving the routine immediately after the error is
>>>> detected.
>>>
>>>
> [...]
>
> Ok let's simplify the code (and add the missing lock):
>
> write_lock_nocancel(&freertos_scheduler.lock);
> freertos_scheduler.state = taskSCHEDULER_NOT_STARTED;
>
> /* cancel all tasks in list */
> while (!pvlist_empty(&freertos_task_list)) {
> task = pvlist_first_entry(&freertos_task_list, struct freertos_task,
> next);
> if (threadobj_lock(&task->thobj) != -EINVAL) {
> if (threadobj_get_magic(&task->thobj) == task_magic) {
> /* need to leave freertos_scheduler.lock since it is
> taken in task_finalizer while we block in
> threadobj_cancel */
> write_unlock(&freertos_scheduler.lock);
> threadobj_cancel(&task->thobj);
> write_lock_nocancel(&freertos_scheduler.lock);
> continue;
> }
> threadobj_unlock(&task->thobj);
> }
> /* Need to release the lock for a while since a task in deletion
> may need it to unregister itself from freertos_task_list */
> write_unlock(&freertos_scheduler.lock);
> struct timespec rqt;
> clockobj_ticks_to_timeout(&freertos_clock,
> 0.001 * xGetTicksPerSecond(),
> &rqt);
> threadobj_sleep(&rqt);
> write_lock_nocancel(&freertos_scheduler.lock);
> }
> write_unlock(&freertos_scheduler.lock);
>
> I had used pvlist_for_each_entry_safe() originally, but due to the possibility
> having to access a single task multiple times, I ended up with two nested loops.
I will include this implementation in my next patch. This patch also includes
changes of comments to c-style and removal of (void)-casting ignored return values.
Also, I have adapted the patch to the latest (warn_unused_result) attributes.
Matthias
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Xenomai] FreeRTOS skin
2014-05-05 10:33 ` Philippe Gerum
` (2 preceding siblings ...)
2014-05-06 17:19 ` Matthias Schneider
@ 2014-05-18 18:30 ` Matthias Schneider
2014-05-19 7:46 ` Philippe Gerum
3 siblings, 1 reply; 21+ messages in thread
From: Matthias Schneider @ 2014-05-18 18:30 UTC (permalink / raw)
To: Philippe Gerum, xenomai@xenomai.org
----- Original Message -----
> From: Philippe Gerum <rpm@xenomai.org>
> To: Matthias Schneider <ma30002000@yahoo.de>; "xenomai@xenomai.org" <xenomai@xenomai.org>
> Cc:
> Sent: Monday, May 5, 2014 12:33 PM
> Subject: Re: [Xenomai] FreeRTOS skin
>
> On 05/04/2014 06:59 PM, Matthias Schneider wrote:
>
>> Hi all,
>>
>> please find enclosed a patch with a FreeRTOS skin for xenomai-forge I have
>> been working on for some time. I would like to get some feedback and advice
>> what still needs to be done to get it accepted in Xenomai. There is a set of
>> unit tests included and the possibility to download the original FreeRTOS package
>> in order to run most of its (platform independent) test suite. Until now I have
>> been working under mercury only. Documentation is available in form of a README
>> file in lib/freertos/README, which should also be a good starting point.
>
> Ok, thanks for this. Let's address issues gradually, starting with the
> task module.
>
[...]
>
> - the read/write_lock_nocancel() form is reserved for protecting
> sections which are known not to traverse cancellation points, as defined
> by POSIX
> (http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html).
> This is about self-documentation of the code, and optimizing execution
> by omitting costly management of cleanup blocks when it is deemed safe
> to do so.
>
> - CANCEL_DEFER() / CANCEL_RESTORE() should protect sections against
> asynchronous cancellation, we typically do this before invoking the
> copperplate layer, so that we may assume that pthread_cancel() won't be
> a problem when running inner code, provided we have been careful about
> handling read/write lock cleanups. These macros work by disabling
> asynchronous cancellation for the current thread when
> --enable-async-cancel was given at build time. Otherwise, this part is a
> nop.
Obviously the *nocancel locks in my previous patch (task.c) were incorrect.
However I am not sure which way to replace them - I see several possibilities:
a)
push_cleanup_lock(&freertos_scheduler.lock);
write_lock(&freertos_scheduler.lock);
//will correctly clean up when thread is cancelled
b)
write_lock_safe(&freertos_scheduler.lock);
// will disable cancellation until lock is released
c)
do no care about locks in cancelled threads and just use
write_lock(&freertos_scheduler.lock)
Since freertos_scheduler.lock is essential for the correct functioning of the
FreeRTOS skin, c) is probably out.
Any hint?
Thanks,
Matthias
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Xenomai] FreeRTOS skin
2014-05-18 18:30 ` Matthias Schneider
@ 2014-05-19 7:46 ` Philippe Gerum
2014-05-20 7:06 ` Matthias Schneider
0 siblings, 1 reply; 21+ messages in thread
From: Philippe Gerum @ 2014-05-19 7:46 UTC (permalink / raw)
To: Matthias Schneider, xenomai@xenomai.org
On 05/18/2014 08:30 PM, Matthias Schneider wrote:
> ----- Original Message -----
>
>> From: Philippe Gerum <rpm@xenomai.org>
>> To: Matthias Schneider <ma30002000@yahoo.de>; "xenomai@xenomai.org" <xenomai@xenomai.org>
>> Cc:
>> Sent: Monday, May 5, 2014 12:33 PM
>> Subject: Re: [Xenomai] FreeRTOS skin
>>
>> On 05/04/2014 06:59 PM, Matthias Schneider wrote:
>>
>>> Hi all,
>>>
>>> please find enclosed a patch with a FreeRTOS skin for xenomai-forge I have
>>> been working on for some time. I would like to get some feedback and advice
>>> what still needs to be done to get it accepted in Xenomai. There is a set of
>>> unit tests included and the possibility to download the original FreeRTOS package
>>> in order to run most of its (platform independent) test suite. Until now I have
>>> been working under mercury only. Documentation is available in form of a README
>>> file in lib/freertos/README, which should also be a good starting point.
>>
>> Ok, thanks for this. Let's address issues gradually, starting with the
>> task module.
>>
> [...]
>>
>> - the read/write_lock_nocancel() form is reserved for protecting
>> sections which are known not to traverse cancellation points, as defined
>> by POSIX
>> (http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html).
>> This is about self-documentation of the code, and optimizing execution
>> by omitting costly management of cleanup blocks when it is deemed safe
>> to do so.
>>
>> - CANCEL_DEFER() / CANCEL_RESTORE() should protect sections against
>> asynchronous cancellation, we typically do this before invoking the
>> copperplate layer, so that we may assume that pthread_cancel() won't be
>> a problem when running inner code, provided we have been careful about
>> handling read/write lock cleanups. These macros work by disabling
>> asynchronous cancellation for the current thread when
>> --enable-async-cancel was given at build time. Otherwise, this part is a
>> nop.
>
> Obviously the *nocancel locks in my previous patch (task.c) were incorrect.
> However I am not sure which way to replace them - I see several possibilities:
>
> a)
> push_cleanup_lock(&freertos_scheduler.lock);
> write_lock(&freertos_scheduler.lock);
> //will correctly clean up when thread is cancelled
>
> b)
> write_lock_safe(&freertos_scheduler.lock);
> // will disable cancellation until lock is released
>
> c)
> do no care about locks in cancelled threads and just use
> write_lock(&freertos_scheduler.lock)
>
> Since freertos_scheduler.lock is essential for the correct functioning of the
> FreeRTOS skin, c) is probably out.
>
> Any hint?
>
I would restrict this lock to protecting manipulations of the task list,
nothing more. It seems to be covering too much code right now. Assuming
this, you would only need the _nocancel form to protect basic list
operations which do not cross any cancellation point.
Having vTaskStartScheduler() wait for task termination should be as
simple as a condvar-based protocol, e.g.
__RT(mutex_lock(&tasklist_lock));
for (;;) {
if (pvlist_empty(&task_list))
break;
__RT(pthread_cond_wait(&tasklist_cond, &tasklist_lock));
}
__RT(mutex_unlock(&tasklist_lock));
You could then synchronize with the task finalizer, e.g.
task_finalizer:
__RT(mutex_lock(&tasklist_lock));
pvlist_remove(&task->next);
if (freertos_scheduler.state != taskSCHEDULER_RUNNING &&
pvlist_empty(&task_list))
__RT(pthread_cond_signal(&tasklist_cond));
__RT(mutex_lock(&tasklist_lock));
I would also introduce a new scheduler state, e.g.
taskSCHEDULER_STOPPING, which could be used to prevent a concurrent call
to vTaskStartScheduler() to respawn the system until the ongoing
shutdown has eventually completed.
PS: The __RT() modifier means to pick the dual kernel version of this
call over Cobalt (i.e. the real-time one implemented by Xenomai), or the
regular glibc one over Mercury. __STD() means to always pick the
glibc-based call, regardless of the real-time core underneath.
If you mention no modifier, either of __RT/__STD may be assumed
depending on whether symbol wrapping is enabled at link time. To prevent
any ambiguity, a skin should always specify the appropriate modifier for
calls the Cobalt core overrides from the glibc, since applications may
or may not require symbol wrapping.
--
Philippe.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Xenomai] FreeRTOS skin
2014-05-19 7:46 ` Philippe Gerum
@ 2014-05-20 7:06 ` Matthias Schneider
2014-05-20 7:53 ` Philippe Gerum
0 siblings, 1 reply; 21+ messages in thread
From: Matthias Schneider @ 2014-05-20 7:06 UTC (permalink / raw)
To: Philippe Gerum, xenomai@xenomai.org
----- Original Message -----
> From: Philippe Gerum <rpm@xenomai.org>
> To: Matthias Schneider <ma30002000@yahoo.de>; "xenomai@xenomai.org" <xenomai@xenomai.org>
> Cc:
> Sent: Monday, May 19, 2014 9:46 AM
> Subject: Re: [Xenomai] FreeRTOS skin
>
> On 05/18/2014 08:30 PM, Matthias Schneider wrote:
>> ----- Original Message -----
>>
>>> From: Philippe Gerum <rpm@xenomai.org>
>>> To: Matthias Schneider <ma30002000@yahoo.de>;
> "xenomai@xenomai.org" <xenomai@xenomai.org>
>>> Cc:
>>> Sent: Monday, May 5, 2014 12:33 PM
>>> Subject: Re: [Xenomai] FreeRTOS skin
>>>
>>> On 05/04/2014 06:59 PM, Matthias Schneider wrote:
>>>
>>>> Hi all,
>>>>
>>>> please find enclosed a patch with a FreeRTOS skin for
> xenomai-forge I have
>>>> been working on for some time. I would like to get some feedback
> and advice
>>>> what still needs to be done to get it accepted in Xenomai. There
> is a set of
>>>> unit tests included and the possibility to download the original
> FreeRTOS package
>>>> in order to run most of its (platform independent) test suite.
> Until now I have
>>>> been working under mercury only. Documentation is available in
> form of a README
>>>> file in lib/freertos/README, which should also be a good starting
> point.
>>>
>>> Ok, thanks for this. Let's address issues gradually, starting with
> the
>>> task module.
>>>
>> [...]
>>>
>>> - the read/write_lock_nocancel() form is reserved for protecting
>>> sections which are known not to traverse cancellation points, as
> defined
>>> by POSIX
>>>
> (http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html).
>>> This is about self-documentation of the code, and optimizing execution
>>> by omitting costly management of cleanup blocks when it is deemed safe
>>> to do so.
>>>
>>> - CANCEL_DEFER() / CANCEL_RESTORE() should protect sections against
>>> asynchronous cancellation, we typically do this before invoking the
>>> copperplate layer, so that we may assume that pthread_cancel()
> won't be
>>> a problem when running inner code, provided we have been careful about
>>> handling read/write lock cleanups. These macros work by disabling
>>> asynchronous cancellation for the current thread when
>>> --enable-async-cancel was given at build time. Otherwise, this part is
> a
>>> nop.
>>
>> Obviously the *nocancel locks in my previous patch (task.c) were incorrect.
>> However I am not sure which way to replace them - I see several
> possibilities:
>>
>> a)
>> push_cleanup_lock(&freertos_scheduler.lock);
>> write_lock(&freertos_scheduler.lock);
>> //will correctly clean up when thread is cancelled
>>
>> b)
>> write_lock_safe(&freertos_scheduler.lock);
>> // will disable cancellation until lock is released
>>
>> c)
>> do no care about locks in cancelled threads and just use
>> write_lock(&freertos_scheduler.lock)
>>
>> Since freertos_scheduler.lock is essential for the correct functioning of
> the
>> FreeRTOS skin, c) is probably out.
>>
>> Any hint?
>>
>
> I would restrict this lock to protecting manipulations of the task list,
> nothing more. It seems to be covering too much code right now. Assuming
> this, you would only need the _nocancel form to protect basic list
> operations which do not cross any cancellation point.
>
> Having vTaskStartScheduler() wait for task termination should be as
> simple as a condvar-based protocol, e.g.
>
> __RT(mutex_lock(&tasklist_lock));
>
> for (;;) {
> if (pvlist_empty(&task_list))
> break;
> __RT(pthread_cond_wait(&tasklist_cond, &tasklist_lock));
> }
>
> __RT(mutex_unlock(&tasklist_lock));
>
> You could then synchronize with the task finalizer, e.g.
>
> task_finalizer:
>
> __RT(mutex_lock(&tasklist_lock));
>
> pvlist_remove(&task->next);
>
> if (freertos_scheduler.state != taskSCHEDULER_RUNNING &&
> pvlist_empty(&task_list))
> __RT(pthread_cond_signal(&tasklist_cond));
>
> __RT(mutex_lock(&tasklist_lock));
>
> I would also introduce a new scheduler state, e.g.
> taskSCHEDULER_STOPPING, which could be used to prevent a concurrent call
> to vTaskStartScheduler() to respawn the system until the ongoing
> shutdown has eventually completed.
>
> PS: The __RT() modifier means to pick the dual kernel version of this
> call over Cobalt (i.e. the real-time one implemented by Xenomai), or the
> regular glibc one over Mercury. __STD() means to always pick the
> glibc-based call, regardless of the real-time core underneath.
>
> If you mention no modifier, either of __RT/__STD may be assumed
> depending on whether symbol wrapping is enabled at link time. To prevent
> any ambiguity, a skin should always specify the appropriate modifier for
> calls the Cobalt core overrides from the glibc, since applications may
> or may not require symbol wrapping.
>
Considering that the simple approach was the one I had originally employed
until I implemented vTaskResumeAll and vTaskSuspendAll
I suppose it all comes down how to implement these two functions.
I am nearly convinced to implement them via threadobj_lock_sched() and
threadobj_unlock_sched(), which should make most of the proposed
re-simplifications possible, but I have still two points:
* On smp machines, it will not behave as expected since the mentioned
functions will prevent the current thread from being scheduled out,
but not from other tasks being executed on other CPUs if I am correct
* functions like vTaskDelay / threadobj_sleep() will not perform as expected
since they may cause the curren task being schduled out.
Is there anything I can do about these?
Also, functions like xTaskIsTaskSuspended() and uxTaskPriorityGet need to be
adapted to return simulated values, but this should be easy.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Xenomai] FreeRTOS skin
2014-05-20 7:06 ` Matthias Schneider
@ 2014-05-20 7:53 ` Philippe Gerum
0 siblings, 0 replies; 21+ messages in thread
From: Philippe Gerum @ 2014-05-20 7:53 UTC (permalink / raw)
To: Matthias Schneider, xenomai@xenomai.org
On 05/20/2014 09:06 AM, Matthias Schneider wrote:
>
>
>
>
>
> ----- Original Message -----
>> From: Philippe Gerum <rpm@xenomai.org>
>> To: Matthias Schneider <ma30002000@yahoo.de>; "xenomai@xenomai.org" <xenomai@xenomai.org>
>> Cc:
>> Sent: Monday, May 19, 2014 9:46 AM
>> Subject: Re: [Xenomai] FreeRTOS skin
>>
>> On 05/18/2014 08:30 PM, Matthias Schneider wrote:
>>> ----- Original Message -----
>>>
>>>> From: Philippe Gerum <rpm@xenomai.org>
>>>> To: Matthias Schneider <ma30002000@yahoo.de>;
>> "xenomai@xenomai.org" <xenomai@xenomai.org>
>>>> Cc:
>>>> Sent: Monday, May 5, 2014 12:33 PM
>>>> Subject: Re: [Xenomai] FreeRTOS skin
>>>>
>>>> On 05/04/2014 06:59 PM, Matthias Schneider wrote:
>>>>
>>>>> Hi all,
>>>>>
>>>>> please find enclosed a patch with a FreeRTOS skin for
>> xenomai-forge I have
>>>>> been working on for some time. I would like to get some feedback
>> and advice
>>>>> what still needs to be done to get it accepted in Xenomai. There
>> is a set of
>>>>> unit tests included and the possibility to download the original
>> FreeRTOS package
>>>>> in order to run most of its (platform independent) test suite.
>> Until now I have
>>>>> been working under mercury only. Documentation is available in
>> form of a README
>>>>> file in lib/freertos/README, which should also be a good starting
>> point.
>>>>
>>>> Ok, thanks for this. Let's address issues gradually, starting with
>> the
>>>> task module.
>>>>
>>> [...]
>>>>
>>>> - the read/write_lock_nocancel() form is reserved for protecting
>>>> sections which are known not to traverse cancellation points, as
>> defined
>>>> by POSIX
>>>>
>> (http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html).
>>>> This is about self-documentation of the code, and optimizing execution
>>>> by omitting costly management of cleanup blocks when it is deemed safe
>>>> to do so.
>>>>
>>>> - CANCEL_DEFER() / CANCEL_RESTORE() should protect sections against
>>>> asynchronous cancellation, we typically do this before invoking the
>>>> copperplate layer, so that we may assume that pthread_cancel()
>> won't be
>>>> a problem when running inner code, provided we have been careful about
>>>> handling read/write lock cleanups. These macros work by disabling
>>>> asynchronous cancellation for the current thread when
>>>> --enable-async-cancel was given at build time. Otherwise, this part is
>> a
>>>> nop.
>>>
>>> Obviously the *nocancel locks in my previous patch (task.c) were incorrect.
>>> However I am not sure which way to replace them - I see several
>> possibilities:
>>>
>>> a)
>>> push_cleanup_lock(&freertos_scheduler.lock);
>>> write_lock(&freertos_scheduler.lock);
>>> //will correctly clean up when thread is cancelled
>>>
>>> b)
>>> write_lock_safe(&freertos_scheduler.lock);
>>> // will disable cancellation until lock is released
>>>
>>> c)
>>> do no care about locks in cancelled threads and just use
>>> write_lock(&freertos_scheduler.lock)
>>>
>>> Since freertos_scheduler.lock is essential for the correct functioning of
>> the
>>> FreeRTOS skin, c) is probably out.
>>>
>>> Any hint?
>>>
>>
>> I would restrict this lock to protecting manipulations of the task list,
>> nothing more. It seems to be covering too much code right now. Assuming
>> this, you would only need the _nocancel form to protect basic list
>> operations which do not cross any cancellation point.
>>
>> Having vTaskStartScheduler() wait for task termination should be as
>> simple as a condvar-based protocol, e.g.
>>
>> __RT(mutex_lock(&tasklist_lock));
>>
>> for (;;) {
>> if (pvlist_empty(&task_list))
>> break;
>> __RT(pthread_cond_wait(&tasklist_cond, &tasklist_lock));
>> }
>>
>> __RT(mutex_unlock(&tasklist_lock));
>>
>> You could then synchronize with the task finalizer, e.g.
>>
>> task_finalizer:
>>
>> __RT(mutex_lock(&tasklist_lock));
>>
>> pvlist_remove(&task->next);
>>
>> if (freertos_scheduler.state != taskSCHEDULER_RUNNING &&
>> pvlist_empty(&task_list))
>> __RT(pthread_cond_signal(&tasklist_cond));
>>
>> __RT(mutex_lock(&tasklist_lock));
>>
>> I would also introduce a new scheduler state, e.g.
>> taskSCHEDULER_STOPPING, which could be used to prevent a concurrent call
>> to vTaskStartScheduler() to respawn the system until the ongoing
>> shutdown has eventually completed.
>>
>> PS: The __RT() modifier means to pick the dual kernel version of this
>> call over Cobalt (i.e. the real-time one implemented by Xenomai), or the
>> regular glibc one over Mercury. __STD() means to always pick the
>> glibc-based call, regardless of the real-time core underneath.
>>
>> If you mention no modifier, either of __RT/__STD may be assumed
>> depending on whether symbol wrapping is enabled at link time. To prevent
>> any ambiguity, a skin should always specify the appropriate modifier for
>> calls the Cobalt core overrides from the glibc, since applications may
>> or may not require symbol wrapping.
>>
>
> Considering that the simple approach was the one I had originally employed
> until I implemented vTaskResumeAll and vTaskSuspendAll
> I suppose it all comes down how to implement these two functions.
>
> I am nearly convinced to implement them via threadobj_lock_sched() and
> threadobj_unlock_sched(), which should make most of the proposed
> re-simplifications possible, but I have still two points:
>
> * On smp machines, it will not behave as expected since the mentioned
> functions will prevent the current thread from being scheduled out,
> but not from other tasks being executed on other CPUs if I am correct
>
Yes. But does the FreeRTOS API spec state that such calls should be
SMP-capable? Is there any FreeRTOS incarnation leveraging multi-core
systems?
> * functions like vTaskDelay / threadobj_sleep() will not perform as expected
> since they may cause the curren task being schduled out.
>
> Is there anything I can do about these?
>
> Also, functions like xTaskIsTaskSuspended() and uxTaskPriorityGet need to be
> adapted to return simulated values, but this should be easy.
>
A more general note about sched locking in a Xenomai environment (both
Cobalt and Mercury):
threadobj_lock/unlock_sched() will not even prevent the locking thread
to be scheduled out, it will prevent involuntary preemption, which is
quite different. If that thread has to block internally for gaining
access to any resource, it will schedule out, including on UP systems
(think of a copy-on-write fault or blocking on a native kernel mutex
with Mercury, or relaxing a thread with Cobalt, both threads holding the
scheduler lock when this happens).
On most legacy RTOS with no MMU or sleeping locks, this won't happen,
therefore blocking voluntarily while holding a sched lock will actually
freeze the system entirely, as this is not considered valid action from
the application. Xenomai allows blocking voluntarily while holding such
lock, which is automatically dropped during the sleep time, because
there are situations imposed on us by the host GPOS which may require this.
Generally speaking, sched locking/unlocking is a fundamentally wrong
locking method: it's just about using a single giant traffic light for
controlling access to resources.
This (anti-)feature is provided only to emulate closely enough those
legacy RTOS APIs for supporting applications, but using it for
synchronizing emulators internally is definitely not the way to go.
In short, sched locking is not simple, it's just coarse-grained and I
would go on to say "unreliable by design" over Mercury, since there is
no way to prevent a thread from being blocked on some kernel resource by
the host GPOS running the emulator. The only option would be to force
all threads to suspend in a signal handler (and make sure they did
before proceeding), which seems to me seriously overkill, given that
such locking construct should be discouraged.
This said, I agree that vTaskResumeAll() and vTaskSuspendAll() should
map over threadobj_unlock_sched() and threadobj_lock_sched()
respectively, hoping for the best possible emulation of the scheduler lock.
--
Philippe.
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2014-05-20 7:53 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-04 16:59 [Xenomai] FreeRTOS skin Matthias Schneider
2014-05-04 18:42 ` Gilles Chanteperdrix
2014-05-04 21:22 ` Matthias Schneider
2014-05-05 7:24 ` Philippe Gerum
2014-05-17 14:40 ` Matthias Schneider
2014-05-05 10:33 ` Philippe Gerum
2014-05-05 13:37 ` Philippe Gerum
2014-05-06 7:09 ` Matthias Schneider
2014-05-06 7:46 ` Philippe Gerum
2014-05-06 7:54 ` Philippe Gerum
2014-05-06 16:50 ` Matthias Schneider
2014-05-17 14:56 ` Matthias Schneider
2014-05-05 14:03 ` Gilles Chanteperdrix
2014-05-05 14:13 ` Philippe Gerum
2014-05-06 17:19 ` Matthias Schneider
2014-05-06 17:47 ` Philippe Gerum
2014-05-06 19:46 ` Matthias Schneider
2014-05-18 18:30 ` Matthias Schneider
2014-05-19 7:46 ` Philippe Gerum
2014-05-20 7:06 ` Matthias Schneider
2014-05-20 7:53 ` Philippe Gerum
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.