Task notification as lightweight event bits

eadlwise wrote on Wednesday, May 09, 2018:

Hi,
I have used event bits in order to enjoy Inter-Task Comm. (ITC) between a task which recieves messages in the form of bits from different tasks and ISRs.

The event bits are fine from usage perspective, but are rather slow from performance perspective.
In order to have better performance, i have tried to migrate to direct task notifications as light-weight event bits, which are better performance wise.

The problem is, that although the the freeRTOS kernel states that notifications can be used as lightweight event bits, i find this to be inaccurate.

From my POV, Event bits can be described as a shared memory that different tasks and ISRs may use for ITC. The exact method for setting, clearing, getting or waiting on the bits is left for the user to decide and design. The freeRTOS APIs allows the manipulation of these bits in a safe manner.
On the other hand, the task notification value is a dedicated 32 bitmap which resides inside the task’s control block.
As opposed to event bits (EBs):

  1. There is no option to extend this bit number of notifications - EBs may be allocated as much as we want (up to memory limitations etc.).
  2. EBs may be used to signal several tasks. Notifications are mainly used to signal only the task which they belong to.
  3. There are several more minor functionality limitation, such as waking on some bit configuration etc.

But as far as i’m concerened, apart from the mentioned constraints (which are acceptable by me), i expect the TNs to have the same (or nearly-approximate) functionality as the event groups.

There seems to be a great difference between the capabilities and methodology of the EBs and TNs.
In particular:

  1. Event group bit set - in the notification value, setting bits option is always accompanied by
    notifying the task, leading to unwanted task wake up.
  2. Event group bit clear - In TN, there is no API which can clear, or test and clear some wanted
    bits. The only way that these bits may be cleared is via the “xTaskNotifyWait” which doesn’t
    seem to be the correct way of just clearing some bits.
  3. Event group bit get - The only apparant way to retrieve the notication bitmap is using the
    “xTaskNotifyAndQuery” with “eNoAction” specified as the wanted action. Alas, the query
    itself results with a new notification delivered to the task! A very unfortunate side effect for a
    mere query mechnism.

Additionaly, There is no way knowing if a notification is pending other then running into the “xTaskNotifyWait”! This seems to be a rather “heavy-weight” option for getting information on “light-weight event bits”.

This is quite unfortunate, as all of those functionalities seem to be rather simple to implement as part of the formal APIs.

So, summing it up: Although the TN are described as a light-weight event bits, the real (formal) functionlity is pretty far from it.
Although performance wiseTNs are better than event bits\groups, the usage of it limits the user for a strict usage pattern and by so limit the possibilities of the user for a more versatile SW design.

The bitter laugh here, that with some additional very light weight APIs (which are definitly easy to implement) the situation would’ve be better by far from the current one.

I will be happy to hear your opinion regarding this matter, and also for you to point out my misunderstanding (if any).

Thanks!
Hagay.

rtel wrote on Wednesday, May 09, 2018:

The event bits are fine from usage perspective, but are rather slow from
performance perspective.

That is true when an event bit is set from an interrupt, because the
actual processing is then deferred to a task (because the processing
doesn’t know how many tasks are to be unblocked and therefore is not
deterministic, and therefore not something FreeRTOS would do from a task).

In order to have better performance, i have tried to migrate to direct
task notifications as lightweight
event bits, which are better performance wise.

That puts some of the processing onus on the receiving task, rather than
the kernel.

The problem is, that although the the freeRTOS kernel states that
notifications can be used as lightweight event bits, i find this to be
inaccurate.

From my POV, Event bits can be described as a shared memory that
different tasks and ISRs may use for ITC. The exact method for
setting,clearing and getting the bits is left for the user to decide and
design. The freeRTOS APIs allows the manipulation of these bits in a
safe manner.
On the other hand, the task notification value is a dedicated 32 bitmap
which resides inside the task’s control block. As opposed to event bits
(EBs):

  1. There is no option to extend this bit number - EBs may be allocated
    as much as we want (up to memory limitations etc.).
  2. EBs may be used to signal several tasks. Notifications are mainly
    used to signal only the task which they belong to.
  3. There are several more minor functionality limitation, such as waking
    on some bit configuration etc.

Yes - if you want the full event bit functionality then you need to use
the event bits object. The task notifications allow a subset of
functionality, with more logic having to be outside of the object:
https://www.freertos.org/RTOS_Task_Notification_As_Event_Group.html

eadlwise wrote on Wednesday, May 09, 2018:

Thanks for the response.
I don’t need the “full event bit functionality” as i’m only using it for single tasks, and only needs several bits from it.

Imagine a task that handles long operations from several other source (e.g. ISRs).
Upon exiting from “xTaskNotifyWait”, the notifications bits are cleared and reflected to a local variable. From this point on, there is no way to know whether the task has received a new notification, or querying the task’s bits without triggering a new notification.
As I said, the only way to perform this is to reenter the “xTaskNotifyWait”.
An API which would’ve just provide some more information (e.g. the current raised bits\notification value) would have been suffice to update the current notification bits without the need to enter the “xTaskNotifyWait” function.

As I said, I’m not expecting the “full event bit functionality” from the TNs. I DO expect that there would be similar service API that gives the same functionality as EBs, up to constant factor.

For me, I have workaround this issues by implementing some APIs which just retrieve some information regarding the notification value\status.
I just don’t understand why so simple, but yet powerful APIs are not included in the formal release APIs, and thus giving a boost to the TNs functionality, to be much more close to the EBs one.