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
+1
View File
@@ -260,6 +260,7 @@ typedef CODE uint16_t (*devif_callback_event_t)(FAR struct net_driver_s *dev,
struct devif_callback_s struct devif_callback_s
{ {
FAR struct devif_callback_s *nxtconn; FAR struct devif_callback_s *nxtconn;
FAR struct devif_callback_s *prevconn;
FAR struct devif_callback_s *nxtdev; FAR struct devif_callback_s *nxtdev;
FAR devif_callback_event_t event; FAR devif_callback_event_t event;
FAR void *priv; FAR void *priv;
+28 -23
View File
@@ -119,41 +119,45 @@ static void devif_callback_free(FAR struct net_driver_s *dev,
if (list_head) if (list_head)
{ {
/* Find the callback structure in the connection event list */ prev = cb->prevconn;
for (prev = NULL, curr = *list_head;
curr && curr != cb;
prev = curr, curr = curr->nxtconn)
{
}
/* Remove the structure from the connection event list */ /* Remove the structure from the connection event list */
DEBUGASSERT(curr); if (prev)
if (curr)
{ {
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 (!cb->nxtconn)
{ {
/* If the tail item is being removed, /* If the tail item is being removed,
* update the tail pointer. * update the tail pointer.
*/ */
DEBUGASSERT(list_tail); DEBUGASSERT(list_tail);
*list_tail = prev; *list_tail = prev;
}
} }
} }
@@ -297,6 +301,7 @@ FAR struct devif_callback_s *
if (list_head && list_tail) if (list_head && list_tail)
{ {
ret->nxtconn = NULL; ret->nxtconn = NULL;
ret->prevconn = *list_tail;
if (*list_tail) if (*list_tail)
{ {