Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[tasklet] add generic tasklet functionality #10027

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

marius-preda
Copy link
Contributor

This commit adds support for a generic tasklet class and object that allows a callback to be executed on the context on the Thread task. This is very usefull for the platform UDP functionality and allows the execution of socket handlers on the context of the OT task instead of the task of the plaftorm UDP.

GenericTasklet functionality and API are now available when OPENTHREAD_CONFIG_GENERIC_TASKLET_ENABLE is enabled

This commit adds support for a generic tasklet class and object that allows a callback
to be executed on the context on the Thread task. This is very usefull for the platform UDP
functionality and allows the execution of socket handlers on the context of the OT task instead
of the task of the plaftorm UDP.

GenericTasklet functionality and API are now available when
OPENTHREAD_CONFIG_GENERIC_TASKLET_ENABLE is enabled
Copy link

size-report bot commented Apr 12, 2024

Size Report of OpenThread

Merging #10027 into main(d0f6d17).

name branch text data bss total
ot-cli-ftd main 467176 856 66364 534396
#10027 467176 856 66364 534396
+/- 0 0 0 0
ot-ncp-ftd main 436076 760 61576 498412
#10027 436076 760 61576 498412
+/- 0 0 0 0
libopenthread-ftd.a main 236220 95 40310 276625
#10027 236220 95 40310 276625
+/- 0 0 0 0
libopenthread-cli-ftd.a main 57549 0 8075 65624
#10027 57549 0 8075 65624
+/- 0 0 0 0
libopenthread-ncp-ftd.a main 31857 0 5916 37773
#10027 31857 0 5916 37773
+/- 0 0 0 0
ot-cli-mtd main 364712 760 51220 416692
#10027 364712 760 51220 416692
+/- 0 0 0 0
ot-ncp-mtd main 347244 760 46448 394452
#10027 347244 760 46448 394452
+/- 0 0 0 0
libopenthread-mtd.a main 158331 0 25182 183513
#10027 158331 0 25182 183513
+/- 0 0 0 0
libopenthread-cli-mtd.a main 39787 0 8059 47846
#10027 39787 0 8059 47846
+/- 0 0 0 0
libopenthread-ncp-mtd.a main 24737 0 5916 30653
#10027 24737 0 5916 30653
+/- 0 0 0 0
ot-cli-ftd-br main 549792 864 131196 681852
#10027 549792 864 131196 681852
+/- 0 0 0 0
libopenthread-ftd-br.a main 322951 100 105118 428169
#10027 322951 100 105118 428169
+/- 0 0 0 0
libopenthread-cli-ftd-br.a main 71212 0 8099 79311
#10027 71212 0 8099 79311
+/- 0 0 0 0
ot-rcp main 62248 564 20604 83416
#10027 62248 564 20604 83416
+/- 0 0 0 0
libopenthread-rcp.a main 9542 0 5052 14594
#10027 9542 0 5052 14594
+/- 0 0 0 0
libopenthread-radio.a main 18870 0 214 19084
#10027 18870 0 214 19084
+/- 0 0 0 0

@marius-preda
Copy link
Contributor Author

Hi @abtink, can you please, have a look at this proposal and let me know what you think?

The general idea behind this PR is to be able to re-use, in an RTOS environment, the openthread task for executing socket handlers of openthread modules that receive data from an external interface. Some examples would be mDNS or Meschop when connecting to an external commissioner.

Packets received on the external interface are processed on the external IP task and are delivered to openthread using platform UDP. We don't want the openthread processing to happen on the external IP task. We also don't want to create another task that handles this processing as it consumes more heap for the stack size. So this new tasklet functionality allows us to handle this problem in a simple and clean way.

There are other external ways to post to the openthread task depending on the application but this solution allows us to make this application and RTOS agnostic.

Thanks!

Copy link
Member

@abtink abtink left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

The feature and code look well-implemented, and I can see its potential usefulness.

However, I believe this functionality is better suited for the platform or OS level, rather than being part of the OpenThread stack and API. We aim to keep OpenThread focused on providing Thread-specific networking capabilities, avoiding extensions that could potentially overlap with OS responsibilities.

Similar to this, we've had requests in the past to expose timer APIs for use by applications. We intentionally avoided this, instead expecting the platform/OS to provide timer functionality.

@@ -51,6 +51,33 @@ extern "C" {
*
*/

#if OPENTHREAD_CONFIG_GENERIC_TASKLET_ENABLE
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Public/platform headers cannot use OPENTHREAD_CONFIG_* definitions because these headers might be included by external projects lacking those definitions.

Instead, we document it as a requirement. "Requires OPENTHREAD_CONFIG_*".

@marius-preda
Copy link
Contributor Author

Thanks!

The feature and code look well-implemented, and I can see its potential usefulness.

However, I believe this functionality is better suited for the platform or OS level, rather than being part of the OpenThread stack and API. We aim to keep OpenThread focused on providing Thread-specific networking capabilities, avoiding extensions that could potentially overlap with OS responsibilities.

Similar to this, we've had requests in the past to expose timer APIs for use by applications. We intentionally avoided this, instead expecting the platform/OS to provide timer functionality.

Hi @abtink, I see your point but am returning to this subject with another idea as we still want to use a simpler solution than creating a new functionality at the platform/OS level. My main goal is to have a Matter and OT example working without specific code in Platform UDP.

The proposed approach is to implement a new platform API, otPlatUdpHandleReceive(otInstance *aInstance, otUdpSocket *aUdpSocket, otMessage *aMessage, otMessageInfo *aInfo) that would handle the socket receive in the context of the OT task.
We would use a tasklet to achieve this. The otPlatUdpHandleReceive would post messages to the tasklet, and then, in the context of the OT task, we would execute the socket handler.

The API description would explain that when a dedicated task is available the socket handler can be executed directly from that task but when there is no such task, this API should be used instead to ensure that the handler is executed in the context of the OT task to prevent any unwanted issues like deadlocks or stack overflows.

What do you think about this idea? If this is a good contribution to the OT stack I will start working on a PR.
Anyway, this draft should be closed after we conclude the discussion.

@abtink
Copy link
Member

abtink commented May 31, 2024

The proposed approach is to implement a new platform API, otPlatUdpHandleReceive(otInstance *aInstance, otUdpSocket *aUdpSocket, otMessage *aMessage, otMessageInfo *aInfo) that would handle the socket receive in the context of the OT task.
We would use a tasklet to achieve this. The otPlatUdpHandleReceive would post messages to the tasklet, and then, in the context of the OT task, we would execute the socket handler.

I am not sure if this would be possible. All OT APIs, callbacks and internal methods must run in the same OS execution context (the same RTOS task or same thread). This would apply to otPlatUdpHandleReceive() and the Tasklet methods.

So if the intention is to allow otPlatUdpHandleReceive() to be called from a different OS context (than the one OT is running on), it wont work and we cannot Post() a Tasklet from a different OS context (say from another RTOS task).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants