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:
Anthony Merlino
2017-06-26 00:58:41 -04:00
parent 3a427d35a3
commit ce8f2735ea
6 changed files with 78 additions and 83 deletions
+5 -20
View File
@@ -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;
} }
+1 -1
View File
@@ -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
+8 -19
View File
@@ -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);
} }
} }
+56 -34
View File
@@ -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 */
+4
View File
@@ -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 */
+4 -9
View File
@@ -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;
} }
} }