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 */
iob_free(txdesc->frame);
((FAR struct mac802154_notif_s *)txdesc->conf)->flink = priv->notif_free;
priv->notif_free = ((FAR struct mac802154_notif_s *)txdesc->conf);
mac802154_notif_free_locked(priv,
(FAR struct ieee802154_notif_s *)txdesc->conf);
mac802154_txdesc_free(priv, txdesc);
priv->beaconupdate = true;
@@ -760,7 +760,6 @@ static void mac802154_txdone_worker(FAR void *arg)
(FAR struct ieee802154_privmac_s *)arg;
FAR struct ieee802154_txdesc_s *txdesc;
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
* 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.
*/
privnotif = (FAR struct mac802154_notif_s *)txdesc->conf;
notif = &privnotif->pub;
notif =(FAR struct ieee802154_notif_s *)txdesc->conf;
switch(txdesc->frametype)
{
@@ -857,14 +855,7 @@ static void mac802154_txdone_worker(FAR void *arg)
break;
default:
/* We can deallocate the data conf notification as it is no
* 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;
mac802154_notif_free_locked(priv, notif);
break;
}
}
@@ -872,13 +863,7 @@ static void mac802154_txdone_worker(FAR void *arg)
default:
{
/* We can deallocate the data conf notification as it is no 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;
mac802154_notif_free_locked(priv, notif);
}
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);
#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)
{
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_notif_s *notif =
(FAR struct ieee802154_notif_s *)txdesc->conf;
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));
}
/* We can deallocate the data conf notification as it is no longer
* needed. We can't use the public function here since we already
* have the MAC locked.
*/
/* Deallocate the data conf notification as it is no longer needed. */
privnotif->flink = priv->notif_free;
priv->notif_free = privnotif;
mac802154_notif_free_locked(priv, notif);
}
}
@@ -524,9 +519,8 @@ void mac802154_txdone_datareq_assoc(FAR struct ieee802154_privmac_s *priv,
FAR struct ieee802154_txdesc_s *txdesc)
{
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_notif_s *notif =
(FAR struct ieee802154_notif_s *)txdesc->conf;
/* If the data request failed to be sent, notify the next layer
* 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_assoctimeout);
/* We can deallocate the data conf notification as it is no longer
* needed. We can't use the public function here since we already
* have the MAC locked.
*/
/* Deallocate the data conf notification as it is no longer needed. */
privnotif->flink = priv->notif_free;
priv->notif_free = privnotif;
mac802154_givesem(&priv->notif_sem);
mac802154_notif_free_locked(priv, notif);
}
}
+56 -34
View File
@@ -69,44 +69,22 @@
*
****************************************************************************/
int mac802154_notif_free(MACHANDLE mac,
FAR struct ieee802154_notif_s *notif)
void mac802154_notif_free(MACHANDLE mac, FAR struct ieee802154_notif_s *notif)
{
FAR struct ieee802154_privmac_s *priv =
(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);
/* We know how many clients have registered for notifications. Each must
* call mac802154_notif_free() before we can release the notification
* resource.
*/
/* Call the internal helper function to free the notification */
if (priv->nnotif < 2)
{
/* This is the free from the last notification */
mac802154_notif_free_locked(priv, notif);
privnotif->flink = priv->notif_free;
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--;
}
/* Unlock the MAC */
mac802154_givesem(&priv->exclsem);
return -ENOTTY;
}
/****************************************************************************
@@ -184,9 +162,9 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv,
if (ret == OK)
{
privnotif = priv->notif_free;
priv->notif_free = privnotif->flink;
priv->nnotif = 0;
privnotif = priv->notif_free;
priv->notif_free = privnotif->flink;
privnotif->nclients = 0;
}
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 */
privnotif = priv->notif_free;
priv->notif_free = privnotif->flink;
priv->nnotif = 0;
privnotif = priv->notif_free;
priv->notif_free = privnotif->flink;
privnotif->nclients = 0;
}
*notif = (FAR struct ieee802154_notif_s *)privnotif;
@@ -230,6 +208,49 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv,
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
*
@@ -242,12 +263,13 @@ void mac802154_notify(FAR struct ieee802154_privmac_s *priv,
FAR struct ieee802154_notif_s *notif)
{
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
* preserved until the final notification.
*/
priv->nnotif = priv->nclients;
privnotif->nclients = priv->nclients;
/* 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 */
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,
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 */
+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)
{
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_notif_s *notif =
(FAR struct ieee802154_notif_s *)txdesc->conf;
/* If the data request failed to be sent, notify the next layer
* 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_polltimeout);
/* We can deallocate the data conf notification as it is no longer
* needed. We can't use the public function here since we already
* have the MAC locked.
*/
/* Deallocate the data conf notification as it is no longer needed. */
privnotif->flink = priv->notif_free;
priv->notif_free = privnotif;
mac802154_notif_free_locked(priv, notif);
}
}