mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 23:03:27 +08:00
ieee802154: Improves notification freeing functionality
Each notification now has a number of clients. When the last client calls free, the notification is freed back to the pool
This commit is contained in:
@@ -636,8 +636,8 @@ static void mac802154_purge_worker(FAR void *arg)
|
|||||||
/* Free the IOB, the notification, and the tx descriptor */
|
/* Free the IOB, the notification, and the tx descriptor */
|
||||||
|
|
||||||
iob_free(txdesc->frame);
|
iob_free(txdesc->frame);
|
||||||
((FAR struct mac802154_notif_s *)txdesc->conf)->flink = priv->notif_free;
|
mac802154_notif_free_locked(priv,
|
||||||
priv->notif_free = ((FAR struct mac802154_notif_s *)txdesc->conf);
|
(FAR struct ieee802154_notif_s *)txdesc->conf);
|
||||||
mac802154_txdesc_free(priv, txdesc);
|
mac802154_txdesc_free(priv, txdesc);
|
||||||
priv->beaconupdate = true;
|
priv->beaconupdate = true;
|
||||||
|
|
||||||
@@ -760,7 +760,6 @@ static void mac802154_txdone_worker(FAR void *arg)
|
|||||||
(FAR struct ieee802154_privmac_s *)arg;
|
(FAR struct ieee802154_privmac_s *)arg;
|
||||||
FAR struct ieee802154_txdesc_s *txdesc;
|
FAR struct ieee802154_txdesc_s *txdesc;
|
||||||
FAR struct ieee802154_notif_s *notif;
|
FAR struct ieee802154_notif_s *notif;
|
||||||
FAR struct mac802154_notif_s *privnotif;
|
|
||||||
|
|
||||||
/* Get exclusive access to the driver structure. We don't care about any
|
/* Get exclusive access to the driver structure. We don't care about any
|
||||||
* signals so don't allow interruptions
|
* signals so don't allow interruptions
|
||||||
@@ -781,8 +780,7 @@ static void mac802154_txdone_worker(FAR void *arg)
|
|||||||
* notification structure to make it easier to use.
|
* notification structure to make it easier to use.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
privnotif = (FAR struct mac802154_notif_s *)txdesc->conf;
|
notif =(FAR struct ieee802154_notif_s *)txdesc->conf;
|
||||||
notif = &privnotif->pub;
|
|
||||||
|
|
||||||
switch(txdesc->frametype)
|
switch(txdesc->frametype)
|
||||||
{
|
{
|
||||||
@@ -857,14 +855,7 @@ static void mac802154_txdone_worker(FAR void *arg)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* We can deallocate the data conf notification as it is no
|
mac802154_notif_free_locked(priv, notif);
|
||||||
* longer needed. We can't use the public function here
|
|
||||||
* since we already have the MAC locked.
|
|
||||||
*/
|
|
||||||
|
|
||||||
privnotif->flink = priv->notif_free;
|
|
||||||
priv->notif_free = privnotif;
|
|
||||||
priv->nnotif = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -872,13 +863,7 @@ static void mac802154_txdone_worker(FAR void *arg)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
/* We can deallocate the data conf notification as it is no longer
|
mac802154_notif_free_locked(priv, notif);
|
||||||
* needed. We can't use the public function here since we already
|
|
||||||
* have the MAC locked.
|
|
||||||
*/
|
|
||||||
|
|
||||||
privnotif->flink = priv->notif_free;
|
|
||||||
priv->notif_free = privnotif;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -368,7 +368,7 @@ int mac802154_resp_orphan(MACHANDLE mac,
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int mac802154_notif_free(MACHANDLE mac,
|
void mac802154_notif_free(MACHANDLE mac,
|
||||||
FAR struct ieee802154_notif_s *notif);
|
FAR struct ieee802154_notif_s *notif);
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
|
|||||||
@@ -402,10 +402,9 @@ void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv,
|
|||||||
FAR struct ieee802154_txdesc_s *txdesc)
|
FAR struct ieee802154_txdesc_s *txdesc)
|
||||||
{
|
{
|
||||||
enum ieee802154_status_e status;
|
enum ieee802154_status_e status;
|
||||||
FAR struct mac802154_notif_s *privnotif =
|
|
||||||
(FAR struct mac802154_notif_s *)txdesc->conf;
|
|
||||||
FAR struct ieee802154_notif_s *notif = &privnotif->pub;
|
|
||||||
FAR struct ieee802154_txdesc_s *respdesc;
|
FAR struct ieee802154_txdesc_s *respdesc;
|
||||||
|
FAR struct ieee802154_notif_s *notif =
|
||||||
|
(FAR struct ieee802154_notif_s *)txdesc->conf;
|
||||||
|
|
||||||
if(txdesc->conf->status != IEEE802154_STATUS_SUCCESS)
|
if(txdesc->conf->status != IEEE802154_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
@@ -497,13 +496,9 @@ void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv,
|
|||||||
(priv->resp_waittime*IEEE802154_BASE_SUPERFRAME_DURATION));
|
(priv->resp_waittime*IEEE802154_BASE_SUPERFRAME_DURATION));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We can deallocate the data conf notification as it is no longer
|
/* Deallocate the data conf notification as it is no longer needed. */
|
||||||
* needed. We can't use the public function here since we already
|
|
||||||
* have the MAC locked.
|
|
||||||
*/
|
|
||||||
|
|
||||||
privnotif->flink = priv->notif_free;
|
mac802154_notif_free_locked(priv, notif);
|
||||||
priv->notif_free = privnotif;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -524,9 +519,8 @@ void mac802154_txdone_datareq_assoc(FAR struct ieee802154_privmac_s *priv,
|
|||||||
FAR struct ieee802154_txdesc_s *txdesc)
|
FAR struct ieee802154_txdesc_s *txdesc)
|
||||||
{
|
{
|
||||||
enum ieee802154_status_e status;
|
enum ieee802154_status_e status;
|
||||||
FAR struct mac802154_notif_s *privnotif =
|
FAR struct ieee802154_notif_s *notif =
|
||||||
(FAR struct mac802154_notif_s *)txdesc->conf;
|
(FAR struct ieee802154_notif_s *)txdesc->conf;
|
||||||
FAR struct ieee802154_notif_s *notif = &privnotif->pub;
|
|
||||||
|
|
||||||
/* If the data request failed to be sent, notify the next layer
|
/* If the data request failed to be sent, notify the next layer
|
||||||
* that the association has failed.
|
* that the association has failed.
|
||||||
@@ -595,14 +589,9 @@ void mac802154_txdone_datareq_assoc(FAR struct ieee802154_privmac_s *priv,
|
|||||||
mac802154_timerstart(priv, priv->max_frame_waittime,
|
mac802154_timerstart(priv, priv->max_frame_waittime,
|
||||||
mac802154_assoctimeout);
|
mac802154_assoctimeout);
|
||||||
|
|
||||||
/* We can deallocate the data conf notification as it is no longer
|
/* Deallocate the data conf notification as it is no longer needed. */
|
||||||
* needed. We can't use the public function here since we already
|
|
||||||
* have the MAC locked.
|
|
||||||
*/
|
|
||||||
|
|
||||||
privnotif->flink = priv->notif_free;
|
mac802154_notif_free_locked(priv, notif);
|
||||||
priv->notif_free = privnotif;
|
|
||||||
mac802154_givesem(&priv->notif_sem);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,44 +69,22 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int mac802154_notif_free(MACHANDLE mac,
|
void mac802154_notif_free(MACHANDLE mac, FAR struct ieee802154_notif_s *notif)
|
||||||
FAR struct ieee802154_notif_s *notif)
|
|
||||||
{
|
{
|
||||||
FAR struct ieee802154_privmac_s *priv =
|
FAR struct ieee802154_privmac_s *priv =
|
||||||
(FAR struct ieee802154_privmac_s *)mac;
|
(FAR struct ieee802154_privmac_s *)mac;
|
||||||
FAR struct mac802154_notif_s *privnotif =
|
|
||||||
(FAR struct mac802154_notif_s *)notif;
|
|
||||||
|
|
||||||
/* Get exclusive access to the MAC */
|
/* Lock the MAC */
|
||||||
|
|
||||||
mac802154_takesem(&priv->exclsem, false);
|
mac802154_takesem(&priv->exclsem, false);
|
||||||
|
|
||||||
/* We know how many clients have registered for notifications. Each must
|
/* Call the internal helper function to free the notification */
|
||||||
* call mac802154_notif_free() before we can release the notification
|
|
||||||
* resource.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (priv->nnotif < 2)
|
mac802154_notif_free_locked(priv, notif);
|
||||||
{
|
|
||||||
/* This is the free from the last notification */
|
|
||||||
|
|
||||||
privnotif->flink = priv->notif_free;
|
/* Unlock the MAC */
|
||||||
priv->notif_free = privnotif;
|
|
||||||
priv->nnotif = 0;
|
|
||||||
|
|
||||||
mac802154_givesem(&priv->notif_sem);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* More calls are expected. Decrement the count of expected calls
|
|
||||||
* and preserve the notification resources.
|
|
||||||
*/
|
|
||||||
|
|
||||||
priv->nnotif--;
|
|
||||||
}
|
|
||||||
|
|
||||||
mac802154_givesem(&priv->exclsem);
|
mac802154_givesem(&priv->exclsem);
|
||||||
return -ENOTTY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -184,9 +162,9 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
if (ret == OK)
|
if (ret == OK)
|
||||||
{
|
{
|
||||||
privnotif = priv->notif_free;
|
privnotif = priv->notif_free;
|
||||||
priv->notif_free = privnotif->flink;
|
priv->notif_free = privnotif->flink;
|
||||||
priv->nnotif = 0;
|
privnotif->nclients = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -220,9 +198,9 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv,
|
|||||||
|
|
||||||
/* We can now safely unlink the next free structure from the free list */
|
/* We can now safely unlink the next free structure from the free list */
|
||||||
|
|
||||||
privnotif = priv->notif_free;
|
privnotif = priv->notif_free;
|
||||||
priv->notif_free = privnotif->flink;
|
priv->notif_free = privnotif->flink;
|
||||||
priv->nnotif = 0;
|
privnotif->nclients = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*notif = (FAR struct ieee802154_notif_s *)privnotif;
|
*notif = (FAR struct ieee802154_notif_s *)privnotif;
|
||||||
@@ -230,6 +208,49 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv,
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mac802154_notif_free_locked
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* When the MAC calls the registered callback, it passes a reference
|
||||||
|
* to a mac802154_notify_s structure. This structure needs to be freed
|
||||||
|
* after the callback handler is done using it.
|
||||||
|
*
|
||||||
|
* Internal version that already has MAC locked
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void mac802154_notif_free_locked(FAR struct ieee802154_privmac_s * priv,
|
||||||
|
FAR struct ieee802154_notif_s *notif)
|
||||||
|
{
|
||||||
|
FAR struct mac802154_notif_s *privnotif =
|
||||||
|
(FAR struct mac802154_notif_s *)notif;
|
||||||
|
|
||||||
|
/* We know how many clients have registered for notifications. Each must
|
||||||
|
* call mac802154_notif_free() before we can release the notification
|
||||||
|
* resource.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (privnotif->nclients < 2)
|
||||||
|
{
|
||||||
|
/* This is the free from the last notification */
|
||||||
|
|
||||||
|
privnotif->flink = priv->notif_free;
|
||||||
|
priv->notif_free = privnotif;
|
||||||
|
privnotif->nclients = 0;
|
||||||
|
|
||||||
|
mac802154_givesem(&priv->notif_sem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* More calls are expected. Decrement the count of expected calls
|
||||||
|
* and preserve the notification resources.
|
||||||
|
*/
|
||||||
|
|
||||||
|
privnotif->nclients--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: mac802154_notify
|
* Name: mac802154_notify
|
||||||
*
|
*
|
||||||
@@ -242,12 +263,13 @@ void mac802154_notify(FAR struct ieee802154_privmac_s *priv,
|
|||||||
FAR struct ieee802154_notif_s *notif)
|
FAR struct ieee802154_notif_s *notif)
|
||||||
{
|
{
|
||||||
FAR struct mac802154_maccb_s *cb;
|
FAR struct mac802154_maccb_s *cb;
|
||||||
|
FAR struct mac802154_notif_s *privnotif = (FAR struct mac802154_notif_s *)notif;
|
||||||
|
|
||||||
/* Set the notification count so that the notification resources will be
|
/* Set the notification count so that the notification resources will be
|
||||||
* preserved until the final notification.
|
* preserved until the final notification.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
priv->nnotif = priv->nclients;
|
privnotif->nclients = priv->nclients;
|
||||||
|
|
||||||
/* Try to notify every registered MAC client */
|
/* Try to notify every registered MAC client */
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ struct mac802154_notif_s
|
|||||||
{
|
{
|
||||||
struct ieee802154_notif_s pub; /* Publically visible structure */
|
struct ieee802154_notif_s pub; /* Publically visible structure */
|
||||||
FAR struct mac802154_notif_s *flink; /* Supports a singly linked list */
|
FAR struct mac802154_notif_s *flink; /* Supports a singly linked list */
|
||||||
|
uint8_t nclients;
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -82,4 +83,7 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv,
|
|||||||
void mac802154_notify(FAR struct ieee802154_privmac_s *priv,
|
void mac802154_notify(FAR struct ieee802154_privmac_s *priv,
|
||||||
FAR struct ieee802154_notif_s *notif);
|
FAR struct ieee802154_notif_s *notif);
|
||||||
|
|
||||||
|
void mac802154_notif_free_locked(FAR struct ieee802154_privmac_s * priv,
|
||||||
|
FAR struct ieee802154_notif_s *notif);
|
||||||
|
|
||||||
#endif /* __WIRELESS_IEEE802154__MAC802154_NOTIF_H */
|
#endif /* __WIRELESS_IEEE802154__MAC802154_NOTIF_H */
|
||||||
@@ -188,9 +188,8 @@ void mac802154_txdone_datareq_poll(FAR struct ieee802154_privmac_s *priv,
|
|||||||
FAR struct ieee802154_txdesc_s *txdesc)
|
FAR struct ieee802154_txdesc_s *txdesc)
|
||||||
{
|
{
|
||||||
enum ieee802154_status_e status;
|
enum ieee802154_status_e status;
|
||||||
FAR struct mac802154_notif_s *privnotif =
|
FAR struct ieee802154_notif_s *notif =
|
||||||
(FAR struct mac802154_notif_s *)txdesc->conf;
|
(FAR struct ieee802154_notif_s *)txdesc->conf;
|
||||||
FAR struct ieee802154_notif_s *notif = &privnotif->pub;
|
|
||||||
|
|
||||||
/* If the data request failed to be sent, notify the next layer
|
/* If the data request failed to be sent, notify the next layer
|
||||||
* that the poll has failed.
|
* that the poll has failed.
|
||||||
@@ -245,13 +244,9 @@ void mac802154_txdone_datareq_poll(FAR struct ieee802154_privmac_s *priv,
|
|||||||
mac802154_timerstart(priv, priv->max_frame_waittime,
|
mac802154_timerstart(priv, priv->max_frame_waittime,
|
||||||
mac802154_polltimeout);
|
mac802154_polltimeout);
|
||||||
|
|
||||||
/* We can deallocate the data conf notification as it is no longer
|
/* Deallocate the data conf notification as it is no longer needed. */
|
||||||
* needed. We can't use the public function here since we already
|
|
||||||
* have the MAC locked.
|
|
||||||
*/
|
|
||||||
|
|
||||||
privnotif->flink = priv->notif_free;
|
mac802154_notif_free_locked(priv, notif);
|
||||||
priv->notif_free = privnotif;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user