sched/wqueue: Add an option to work queue notifier so that the notification can occur on different work queues.

This commit is contained in:
Gregory Nutt
2018-09-11 07:22:23 -06:00
parent 39df7ed0c0
commit af0ee3c8f7
8 changed files with 61 additions and 54 deletions
+8 -7
View File
@@ -279,7 +279,7 @@ struct work_s
};
/* This is an enumeration of the various events that may be
* notified via nxig_notifier_signal().
* notified via work_notifier_signal().
*/
enum work_evtype_e
@@ -288,7 +288,7 @@ enum work_evtype_e
WORK_NET_DOWN, /* Notify that the network is down */
WORK_TCP_READAHEAD, /* Notify that TCP read-ahead data is available */
WORK_TCP_DISCONNECT, /* Notify loss of TCP connection */
WORK_UDP_READAHEAD, /* Notify that TCP read-ahead data is available */
WORK_UDP_READAHEAD /* Notify that TCP read-ahead data is available */
};
/* This structure describes one notification */
@@ -296,6 +296,7 @@ enum work_evtype_e
struct work_notifier_s
{
uint8_t evtype; /* See enum work_evtype_e */
uint8_t wqueue; /* The work queue to use: HPWORK or LPWORK */
FAR void *qualifier; /* Event qualifier value */
FAR void *arg; /* User-defined worker function argument */
worker_t worker; /* The worker function to schedule */
@@ -471,7 +472,7 @@ void lpwork_restorepriority(uint8_t reqprio);
* Name: work_notifier_setup
*
* Description:
* Set up to provide a notification when event is signaled.
* Set up to provide a notification when event occurs.
*
* Input Parameters:
* info - Describes the work notification.
@@ -480,8 +481,8 @@ void lpwork_restorepriority(uint8_t reqprio);
* > 0 - The key which may be used later in a call to
* work_notifier_teardown().
* == 0 - Not used (reserved for wrapper functions).
* < 0 - An unexpected error occurred and no signal will be sent. The
* returned value is a negated errno value that indicates the
* < 0 - An unexpected error occurred and no notification will be sent.
* The returned value is a negated errno value that indicates the
* nature of the failure.
*
****************************************************************************/
@@ -497,7 +498,7 @@ int work_notifier_setup(FAR struct work_notifier_s *info);
* Eliminate a notification previously setup by work_notifier_setup().
* This function should only be called if the notification should be
* aborted prior to the notification. The notification will automatically
* be torn down after the signal is sent.
* be torn down after the notification is executed.
*
* Input Parameters:
* key - The key value returned from a previous call to
@@ -517,7 +518,7 @@ int work_notifier_teardown(int key);
* Name: work_notifier_signal
*
* Description:
* An event has just occurred. Signal all threads waiting for that event.
* An event has just occurred. Notify all threads waiting for that event.
*
* When an event of interest occurs, *all* of the workers waiting for this
* event will be executed. If there are multiple workers for a resource
+1
View File
@@ -63,6 +63,7 @@ config IOB_NOTIFIER
bool "Support IOB notifications"
default n
depends on SCHED_HPWORK
select WQUEUE_NOTIFIER
---help---
Enable building of IOB notifier logic that will execute a worker
function on the high priority work queue when an IOB is available.
+6 -7
View File
@@ -68,12 +68,10 @@
* function when it runs.
*
* Returned Value:
* > 0 - The signal notification is in place. The returned value is a
* key that may be used later in a call to
* iob_notifier_teardown().
* == 0 - There are already free IOBs. No signal notification will be
* provided.
* < 0 - An unexpected error occurred and no signal will be sent. The
* > 0 - The notification is in place. The returned value is a key that
* may be used later in a call to iob_notifier_teardown().
* == 0 - There are already free IOBs. No notification will be provided.
* < 0 - An unexpected error occurred and notification will occur. The
* returned value is a negated errno value that indicates the
* nature of the failure.
*
@@ -97,6 +95,7 @@ int iob_notifier_setup(worker_t worker, FAR void *arg)
/* Otherwise, this is just a simple wrapper around work_notifer_setup(). */
info.evtype = WORK_IOB_AVAIL;
info.wqueue = HPWORK;
info.qualifier = NULL;
info.arg = arg;
info.worker = worker;
@@ -111,7 +110,7 @@ int iob_notifier_setup(worker_t worker, FAR void *arg)
* Eliminate an IOB notification previously setup by iob_notifier_setup().
* This function should only be called if the notification should be
* aborted prior to the notification. The notification will automatically
* be torn down after the signal is sent.
* be torn down after the notification.
*
* Input Parameters:
* key - The key value returned from a previous call to
+3 -2
View File
@@ -39,9 +39,10 @@ config NETDEV_IFINDEX
config NETDOWN_NOTIFIER
bool "Support network down notifications"
default n
depends on SCHED_HPWORK
depends on SCHED_LPWORK
select WQUEUE_NOTIFIER
---help---
Enable building of logic that will execute on the high priority work
Enable building of logic that will execute on the low priority work
thread when the network is taken down. This is is a general purpose
notifier, but was developed specifically to support SIGHUP poll()
logic.
+10 -10
View File
@@ -59,22 +59,21 @@
*
* Description:
* Set up to perform a callback to the worker function the network goes
* down. The worker function will execute on the high priority worker
* down. The worker function will execute on the low priority worker
* thread.
*
* Input Parameters:
* worker - The worker function to execute on the high priority work
* queue when data is available in the UDP readahead buffer.
* worker - The worker function to execute on the low priority work
* queue when data is available in the UDP read-ahead buffer.
* dev - The network driver to be monitored
* arg - A user-defined argument that will be available to the worker
* function when it runs.
* Returned Value:
* > 0 - The signal notification is in place. The returned value is a
* key that may be used later in a call to
* netdown_notifier_teardown().
* == 0 - The the device is already down. No signal notification will
* be provided.
* < 0 - An unexpected error occurred and no signal will be sent. The
* > 0 - The notification is in place. The returned value is a key that
* may be used later in a call to netdown_notifier_teardown().
* == 0 - The the device is already down. No notification will be
* provided.
* < 0 - An unexpected error occurred and notification will occur. The
* returned value is a negated errno value that indicates the
* nature of the failure.
*
@@ -99,6 +98,7 @@ int netdown_notifier_setup(worker_t worker, FAR struct net_driver_s *dev,
/* Otherwise, this is just a simple wrapper around work_notifer_setup(). */
info.evtype = WORK_NET_DOWN;
info.wqueue = LPWORK;
info.qualifier = dev;
info.arg = arg;
info.worker = worker;
@@ -113,7 +113,7 @@ int netdown_notifier_setup(worker_t worker, FAR struct net_driver_s *dev,
* Eliminate a network down notification previously setup by
* netdown_notifier_setup(). This function should only be called if the
* notification should be aborted prior to the notification. The
* notification will automatically be torn down after the signal is sent.
* notification will automatically be torn down after the notification.
*
* Input Parameters:
* key - The key value returned from a previous call to
+3 -2
View File
@@ -50,10 +50,11 @@ config NET_MAX_LISTENPORTS
config TCP_NOTIFIER
bool "Support TCP notifications"
default n
depends on SCHED_HPWORK
depends on SCHED_LPWORK
select WQUEUE_NOTIFIER
---help---
Enable building of TCP notifier logic that will execute a worker
function on the high priority work queue when read-ahead data
function on the low priority work queue when read-ahead data
is available or when a TCP connection is lost. This is is a general
purpose notifier, but was developed specifically to support poll()
logic where the poll must wait for these events.
+16 -16
View File
@@ -60,22 +60,21 @@
* Description:
* Set up to perform a callback to the worker function when an TCP data
* is added to the read-ahead buffer. The worker function will execute
* on the high priority worker thread.
* on the low priority worker thread.
*
* Input Parameters:
* worker - The worker function to execute on the high priority work
* worker - The worker function to execute on the low priority work
* queue when data is available in the TCP read-ahead buffer.
* conn - The TCP connection where read-ahead data is needed.
* arg - A user-defined argument that will be available to the worker
* function when it runs.
*
* Returned Value:
* > 0 - The signal notification is in place. The returned value is a
* key that may be used later in a call to
* tcp_notifier_teardown().
* == 0 - There is already buffered read-ahead data. No signal
* notification will be provided.
* < 0 - An unexpected error occurred and no signal will be sent. The
* > 0 - The notification is in place. The returned value is a key that
* may be used later in a call to tcp_notifier_teardown().
* == 0 - There is already buffered read-ahead data. No notification
* will be provided.
* < 0 - An unexpected error occurred and notification will ocur. The
* returned value is a negated errno value that indicates the
* nature of the failure.
*
@@ -101,6 +100,7 @@ int tcp_readahead_notifier_setup(worker_t worker,
/* Otherwise, this is just a simple wrapper around work_notifer_setup(). */
info.evtype = WORK_TCP_READAHEAD;
info.wqueue = LPWORK;
info.qualifier = conn;
info.arg = arg;
info.worker = worker;
@@ -116,19 +116,18 @@ int tcp_readahead_notifier_setup(worker_t worker,
* connection is lost.
*
* Input Parameters:
* worker - The worker function to execute on the high priority work
* worker - The worker function to execute on the low priority work
* queue when data is available in the TCP read-ahead buffer.
* conn - The TCP connection where read-ahead data is needed.
* arg - A user-defined argument that will be available to the worker
* function when it runs.
*
* Returned Value:
* > 0 - The signal notification is in place. The returned value is a
* key that may be used later in a call to
* tcp_notifier_teardown().
* == 0 - There is already buffered read-ahead data. No signal
* notification will be provided.
* < 0 - An unexpected error occurred and no signal will be sent. The
* > 0 - The notification is in place. The returned value is a key that
* may be used later in a call to tcp_notifier_teardown().
* == 0 - There is already buffered read-ahead data. No notification
* will be provided.
* < 0 - An unexpected error occurred and notification will occur. The
* returned value is a negated errno value that indicates the
* nature of the failure.
*
@@ -152,6 +151,7 @@ int tcp_readahead_disconnect_setup(worker_t worker,
/* Otherwise, this is just a simple wrapper around work_notifer_setup(). */
info.evtype = WORK_TCP_DISCONNECT;
info.wqueue = LPWORK;
info.qualifier = conn;
info.arg = arg;
info.worker = worker;
@@ -166,7 +166,7 @@ int tcp_readahead_disconnect_setup(worker_t worker,
* Eliminate a TCP read-ahead notification previously setup by
* tcp_readahead_notifier_setup(). This function should only be called
* if the notification should be aborted prior to the notification. The
* notification will automatically be torn down after the signal is sent.
* notification will automatically be torn down after the notifcation.
*
* Input Parameters:
* key - The key value returned from a previous call to
+14 -10
View File
@@ -51,7 +51,7 @@
#include <nuttx/semaphore.h>
#include <nuttx/wqueue.h>
#include "signal/signal.h"
#include "wqueue/wqueue.h"
#ifdef CONFIG_WQUEUE_NOTIFIER
@@ -85,8 +85,8 @@ struct work_notifier_entry_s
/* This is a singly linked list of pending notifications. When an event
* occurs available, *all* of the waiters for that event in this list will
* be signaled and the entry will be freed. If there are multiple waiters
* for some resource, then only the highest priority thread will get the
* be notified and the entry will be freed. If there are multiple waiters
* for some resource, then only the first to execute thread will get the
* resource. Lower priority threads will need to call work_notifier_setup()
* once again.
*/
@@ -182,7 +182,7 @@ static int16_t work_notifier_key(void)
* Name: work_notifier_setup
*
* Description:
* Set up to provide a notification when event is signaled.
* Set up to provide a notification when an event occurs.
*
* Input Parameters:
* info - Describes the work notification.
@@ -191,8 +191,8 @@ static int16_t work_notifier_key(void)
* > 0 - The key which may be used later in a call to
* work_notifier_teardown().
* == 0 - Not used (reserved for wrapper functions).
* < 0 - An unexpected error occurred and no signal will be sent. The
* returned value is a negated errno value that indicates the
* < 0 - An unexpected error occurred and no notification will be sent.
* The returned value is a negated errno value that indicates the
* nature of the failure.
*
****************************************************************************/
@@ -202,6 +202,9 @@ int work_notifier_setup(FAR struct work_notifier_s *info)
FAR struct work_notifier_entry_s *notifier;
int ret;
DEBUGASSERT(info != NULL && info->worker != NULL);
DEBUGASSERT(info->wqueue == HPWORK && info->wqueue == LPWORK);
/* Get exclusive access to the notifier data structures */
ret = nxsem_wait(&g_notifier_sem);
@@ -252,7 +255,7 @@ int work_notifier_setup(FAR struct work_notifier_s *info)
* Eliminate a notification previously setup by work_notifier_setup().
* This function should only be called if the notification should be
* aborted prior to the notification. The notification will automatically
* be torn down after the signal is sent.
* be torn down after the notification executes.
*
* Input Parameters:
* key - The key value returned from a previous call to
@@ -316,7 +319,7 @@ int work_notifier_teardown(int key)
* Name: work_notifier_signal
*
* Description:
* An event has just occurred. Signal all threads waiting for that event.
* An event has just occurred. Notify all threads waiting for that event.
*
* When an event of interest occurs, *all* of the workers waiting for this
* event will be executed. If there are multiple workers for a resource
@@ -334,7 +337,7 @@ int work_notifier_teardown(int key)
****************************************************************************/
void work_notifier_signal(enum work_evtype_e evtype,
FAR void *qualifier)
FAR void *qualifier)
{
FAR struct work_notifier_entry_s *notifier;
FAR struct work_notifier_entry_s *prev;
@@ -392,7 +395,8 @@ void work_notifier_signal(enum work_evtype_e evtype,
/* Schedule the work */
(void)work_queue(HPWORK, &notifier->work, info->worker, info, 0);
(void)work_queue(info->wqueue, &notifier->work, info->worker,
info, 0);
}
else
{