From 47a579f54f4f45289363a30d8ff6def8e31bcb53 Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Mon, 21 Sep 2015 23:54:16 +0200 Subject: [PATCH] documentation: rawapi: improved documentation on multithreading state Based from the current lwIP wiki and my own, improved documentation about the current lwIP multithreading state. --- doc/rawapi.txt | 47 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/doc/rawapi.txt b/doc/rawapi.txt index b492c576..da024943 100644 --- a/doc/rawapi.txt +++ b/doc/rawapi.txt @@ -8,6 +8,12 @@ to use for communication with the TCP/IP code: * higher-level "sequential" API. * BSD-style socket API. +The raw API (sometimes called native API) is an event-driven API designed +to be used without an operating system that implements zero-copy send and +receive. This API is also used by the core stack for interaction between +the various protocols. It is the only API available when running lwIP +without an operating system. + The sequential API provides a way for ordinary, sequential, programs to use the lwIP stack. It is quite similar to the BSD socket API. The model of execution is based on the blocking open-read-write-close @@ -22,14 +28,17 @@ on other platforms (e.g. unix / windows etc.). However, due to limitations in the specification of this API, there might be incompatibilities that require small modifications of existing programs. -** Threading +** Multithreading lwIP started targeting single-threaded environments. When adding multi- threading support, instead of making the core thread-safe, another approach was chosen: there is one main thread running the lwIP core -(also known as the "tcpip_thread"). The raw API may only be used from -this thread! Application threads using the sequential- or socket API -communicate with this main thread through message passing. +(also known as the "tcpip_thread"). When running in a multithreaded +environment, raw API functions MUST only be called from the core thread +since raw API functions are not protected from concurrent access (aside +from pbuf- and memory management functions). Application threads using +the sequential- or socket API communicate with this main thread through +message passing. As such, the list of functions that may be called from other threads or an ISR is very limited! Only functions @@ -47,13 +56,18 @@ communicate with this main thread through message passing. since they are protected by SYS_LIGHTWEIGHT_PROT and/or semaphores. - Only since 1.3.0, if SYS_LIGHTWEIGHT_PROT is set to 1 - and LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT is set to 1, + Netconn or Socket API functions are thread safe against the + core thread but they are not reentrant at the control block + granularity level. That is, a UDP or TCP control block must + not be shared among multiple threads without proper locking. + + If SYS_LIGHTWEIGHT_PROT is set to 1 and + LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT is set to 1, pbuf_free() may also be called from another thread or an ISR (since only then, mem_free - for PBUF_RAM - may be called from an ISR: otherwise, the HEAP is only protected by semaphores). - + ** The remainder of this document discusses the "raw" API. ** @@ -72,13 +86,28 @@ the raw TCP/IP interface are more difficult to understand. Still, this is the preferred way of writing applications that should be small in code size and memory usage. -Both APIs can be used simultaneously by different application +All APIs can be used simultaneously by different application programs. In fact, the sequential API is implemented as an application program using the raw TCP/IP interface. +Do not confuse the LwIP raw API with raw ethernet or ip sockets. +The former is a way of interfacing the lwip network stack (including +tcp and udp), the later refers to processing raw ethernet or ip data +instead of tcp connections or udp packets. + +Raw API applications may never block since all packet processing +(input and output) as well as timer processing (TCP mainly) is done +in a single execution context. + --- Callbacks -Program execution is driven by callbacks. Each callback is an ordinary +Program execution is driven by callbacks functions, which are then +invoked by the lwIP core when activity related to that application +occurs. A particular application may register to be notified via a +callback function for events such as incoming data available, outgoing +data sent, error notifications, poll timer expiration, connection +closed, etc. An application can provide a callback function to perform +processing for any or all of these events. Each callback is an ordinary C function that is called from within the TCP/IP code. Every callback function is passed the current TCP or UDP connection state as an argument. Also, in order to be able to keep program specific state,