net/devif/devif_callback.c: made the connection event list doubly linked.

The resulting time complexities are as follows:
* devif_callback_alloc() time complexity is O(1) (i.e. O(n) to fill the whole list).
* devif_callback_free() time complexity is O(1) (i.e. O(n) to empty the whole list).
* devif_conn_event() time complexity is O(n).
This commit is contained in:
Alexander Lunev 2021-09-21 06:43:31 +03:00 committed by Xiang Xiao
parent beba1056a8
commit 4ac7945676
2 changed files with 29 additions and 23 deletions

View File

@ -260,6 +260,7 @@ typedef CODE uint16_t (*devif_callback_event_t)(FAR struct net_driver_s *dev,
struct devif_callback_s
{
FAR struct devif_callback_s *nxtconn;
FAR struct devif_callback_s *prevconn;
FAR struct devif_callback_s *nxtdev;
FAR devif_callback_event_t event;
FAR void *priv;

View File

@ -119,41 +119,45 @@ static void devif_callback_free(FAR struct net_driver_s *dev,
if (list_head)
{
/* Find the callback structure in the connection event list */
for (prev = NULL, curr = *list_head;
curr && curr != cb;
prev = curr, curr = curr->nxtconn)
{
}
prev = cb->prevconn;
/* Remove the structure from the connection event list */
DEBUGASSERT(curr);
if (curr)
if (prev)
{
if (prev)
/* The item to be removed is not in the head. */
prev->nxtconn = cb->nxtconn;
if (cb->nxtconn)
{
/* The found item to be removed is not in the head. */
/* The item to be removed is not in the tail. */
prev->nxtconn = cb->nxtconn;
cb->nxtconn->prevconn = prev;
}
else
}
else
{
/* The item to be removed is in the head. */
*list_head = cb->nxtconn;
if (cb->nxtconn)
{
/* The found item to be removed is in the head. */
/* There are more items besides the head item. */
*list_head = cb->nxtconn;
cb->nxtconn->prevconn = NULL;
}
}
if (!cb->nxtconn)
{
/* If the tail item is being removed,
* update the tail pointer.
*/
if (!cb->nxtconn)
{
/* If the tail item is being removed,
* update the tail pointer.
*/
DEBUGASSERT(list_tail);
*list_tail = prev;
}
DEBUGASSERT(list_tail);
*list_tail = prev;
}
}
@ -297,6 +301,7 @@ FAR struct devif_callback_s *
if (list_head && list_tail)
{
ret->nxtconn = NULL;
ret->prevconn = *list_tail;
if (*list_tail)
{