t_tasks.c revision 92f26881551da924db36b179757a2d7ea7fc2209
/*
* Copyright (C) 2004, 2005, 2007, 2009, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001 Internet Software Consortium.
*
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: t_tasks.c,v 1.45 2011/03/14 14:10:23 fdupont Exp $ */
#include <config.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef HAVE_INTTYPES_H
#include <inttypes.h> /* uintptr_t */
#endif
#include <isc/condition.h>
#include <isc/platform.h>
#ifdef ISC_PLATFORM_USETHREADS
#else
#endif
static int senders[4];
static void
require_threads(void) {
t_info("This test requires threads\n");
return;
}
static void
int i;
int j;
j = 0;
for (i = 0; i < 1000000; i++)
j += 100;
}
static void
}
static void
}
/*
* Adapted from RTH's original task_test program
*/
static int
t_tasks1(void) {
char *p;
unsigned int workers;
struct isc_interval interval;
workers = 2;
p = t_getenv("ISC_TASK_WORKERS");
if (p != NULL)
if (workers < 1) {
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
return(T_FAIL);
}
if (isc_result != ISC_R_SUCCESS) {
return(T_FAIL);
}
if (isc_result != ISC_R_SUCCESS) {
return(T_FAIL);
}
if (isc_result != ISC_R_SUCCESS) {
return(T_FAIL);
}
if (isc_result != ISC_R_SUCCESS) {
return(T_FAIL);
}
if (isc_result != ISC_R_SUCCESS) {
return(T_FAIL);
}
if (isc_result != ISC_R_SUCCESS) {
return(T_FAIL);
}
if (isc_result != ISC_R_SUCCESS) {
return(T_FAIL);
}
if (isc_result != ISC_R_SUCCESS) {
return(T_FAIL);
}
if (isc_result != ISC_R_SUCCESS) {
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
return(T_UNRESOLVED);
}
sleep(2);
/*
* Note: (void *)1 is used as a sender here, since some compilers
* don't like casting a function pointer to a (void *).
*
* In a real use, it is more likely the sender would be a
* structure (socket, timer, task, etc) but this is just a test
* program.
*/
sizeof(*event));
t_info("isc_event_allocate failed\n");
return(T_UNRESOLVED);
}
sizeof(*event));
t_info("isc_event_allocate failed\n");
return(T_UNRESOLVED);
}
sizeof(*event));
t_info("isc_event_allocate failed\n");
return(T_UNRESOLVED);
}
sizeof(*event));
t_info("isc_event_allocate failed\n");
return(T_UNRESOLVED);
}
sizeof(*event));
t_info("isc_event_allocate failed\n");
return(T_UNRESOLVED);
}
sizeof(*event));
t_info("isc_event_allocate failed\n");
return(T_UNRESOLVED);
}
sizeof(*event));
t_info("isc_event_allocate failed\n");
return(T_UNRESOLVED);
}
sizeof(*event));
t_info("isc_event_allocate failed\n");
return(T_UNRESOLVED);
}
sizeof(*event));
t_info("isc_event_allocate failed\n");
return(T_UNRESOLVED);
}
sizeof(*event));
t_info("isc_event_allocate failed\n");
return(T_UNRESOLVED);
}
sizeof(*event));
t_info("isc_event_allocate failed\n");
return(T_UNRESOLVED);
}
sizeof(*event));
t_info("isc_event_allocate failed\n");
return(T_UNRESOLVED);
}
sizeof(*event));
t_info("isc_event_allocate failed\n");
return(T_UNRESOLVED);
}
sizeof(*event));
t_info("isc_event_allocate failed\n");
return(T_UNRESOLVED);
}
sizeof(*event));
t_info("isc_event_allocate failed\n");
return(T_UNRESOLVED);
}
sleep(10);
return(T_PASS);
}
static const char *a1 = "The task subsystem can create and manage tasks";
static void
t1(void) {
int result;
}
#define T2_NTASKS 10000
static isc_event_t *T2_event;
static isc_taskmgr_t *T2_manager;
static isc_condition_t T2_cv;
static isc_mutex_t T2_mx;
static int T2_done;
static int T2_nprobs;
static int T2_nfails;
static int T2_ntasks;
static void
}
else {
if (isc_result != ISC_R_SUCCESS) {
++T2_nprobs;
}
T2_done = 1;
if (isc_result != ISC_R_SUCCESS) {
++T2_nprobs;
}
if (isc_result != ISC_R_SUCCESS) {
++T2_nprobs;
}
}
}
static void
++T2_ntasks;
}
/*
* Create a new task and forward the message.
*/
if (isc_result != ISC_R_SUCCESS) {
++T2_nfails;
return;
}
(void *)task);
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_task_onshutdown failed %d\n",
++T2_nfails;
return;
}
} else {
/*
* Time to unwind, shutdown should perc back up.
*/
}
}
static int
t_tasks2(void) {
int result;
char *p;
unsigned int workers;
T2_manager = NULL;
T2_done = 0;
T2_nprobs = 0;
T2_nfails = 0;
T2_ntasks = 0;
workers = 2;
p = t_getenv("ISC_TASK_WORKERS");
if (p != NULL)
if (workers < 1) {
return(T_UNRESOLVED);
}
p = t_getenv("ISC_TASKS_MIN");
if (p != NULL)
else
if (ntasks == 0U) {
t_info("Bad config value for ISC_TASKS_MIN, %lu\n",
(unsigned long)ntasks);
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
return(T_FAIL);
}
t_info("isc_event_allocate failed\n");
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
return(T_UNRESOLVED);
}
while (T2_done == 0) {
if (isc_result != ISC_R_SUCCESS) {
return(T_UNRESOLVED);
}
}
else if (T2_nfails != 0)
return(result);
}
static const char *a2 = "The task subsystem can create ISC_TASKS_MIN tasks";
static void
t2(void) {
if (threaded)
else
}
#define T3_NEVENTS 256
static int T3_flag;
static int T3_nevents;
static int T3_nsdevents;
static isc_mutex_t T3_mx;
static isc_condition_t T3_cv;
static int T3_nfails;
static int T3_nprobs;
static void
if (T3_nevents != T3_NEVENTS) {
t_info("Some events were not processed\n");
++T3_nprobs;
}
if (T3_nsdevents == 1) {
++T3_nsdevents;
} else {
t_info("Shutdown events not processed in LIFO order\n");
++T3_nfails;
}
}
static void
if (T3_nevents != T3_NEVENTS) {
t_info("Some events were not processed\n");
++T3_nprobs;
}
if (T3_nsdevents == 0) {
++T3_nsdevents;
} else {
t_info("Shutdown events not processed in LIFO order\n");
++T3_nfails;
}
}
static void
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_lock failed %s\n",
++T3_nprobs;
}
while (T3_flag != 1) {
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_unlock failed %s\n",
++T3_nprobs;
}
}
static void
++T3_nevents;
}
static int
t_tasks3(void) {
int cnt;
int result;
char *p;
unsigned int workers;
T3_flag = 0;
T3_nevents = 0;
T3_nsdevents = 0;
T3_nfails = 0;
T3_nprobs = 0;
event_type = 3;
workers = 2;
p = t_getenv("ISC_TASK_WORKERS");
if (p != NULL)
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mem_create failed %s\n",
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_init failed %s\n",
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_condition_init failed %s\n",
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_taskmgr_create failed %s\n",
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_lock failed %s\n",
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_task_create failed %s\n",
(void) isc_mutex_unlock(&T3_mx);
return(T_UNRESOLVED);
}
/*
* This event causes the task to wait on T3_cv.
*/
/*
* Now we fill up the task's event queue with some events.
*/
}
/*
* Now we register two shutdown events.
*/
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_task_send failed %s\n",
(void) isc_mutex_unlock(&T3_mx);
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_task_send failed %s\n",
(void) isc_mutex_unlock(&T3_mx);
return(T_UNRESOLVED);
}
/*
* Now we free the task by signaling T3_cv.
*/
T3_flag = 1;
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_task_send failed %s\n",
++T3_nprobs;
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_task_send failed %s\n",
++T3_nprobs;
}
if (T3_nsdevents != 2) {
++T3_nfails;
}
if (T3_nfails != 0)
return(result);
}
static const char *a3 = "When isc_task_shutdown() is called, any shutdown "
"events that have been requested via prior "
"isc_task_onshutdown() calls are posted in "
"LIFO order.";
static void
t3(void) {
if (threaded)
else
}
static isc_mutex_t T4_mx;
static isc_condition_t T4_cv;
static int T4_flag;
static int T4_nprobs;
static int T4_nfails;
static void
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_lock failed %s\n",
++T4_nprobs;
}
while (T4_flag != 1) {
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_unlock failed %s\n",
++T4_nprobs;
}
}
static void
/*
* No-op.
*/
}
static int
t_tasks4(void) {
int result;
char *p;
unsigned int workers;
T4_nprobs = 0;
T4_nfails = 0;
T4_flag = 0;
event_type = 4;
workers = 2;
p = t_getenv("ISC_TASK_WORKERS");
if (p != NULL)
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mem_create failed %s\n",
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_init failed %s\n",
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_condition_init failed %s\n",
DESTROYLOCK(&T4_mx);
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_taskmgr_create failed %s\n",
DESTROYLOCK(&T4_mx);
(void) isc_condition_destroy(&T4_cv);
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_lock failed %s\n",
DESTROYLOCK(&T4_mx);
(void) isc_condition_destroy(&T4_cv);
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_task_create failed %s\n",
DESTROYLOCK(&T4_mx);
(void) isc_condition_destroy(&T4_cv);
return(T_UNRESOLVED);
}
/*
* This event causes the task to wait on T4_cv.
*/
if (isc_result != ISC_R_SHUTTINGDOWN) {
t_info("isc_task_onshutdown returned %s\n",
++T4_nfails;
}
/*
* Release the task.
*/
T4_flag = 1;
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_condition_signal failed %s\n",
++T4_nprobs;
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_unlock failed %s\n",
++T4_nprobs;
}
(void) isc_condition_destroy(&T4_cv);
DESTROYLOCK(&T4_mx);
if (T4_nfails != 0)
return(result);
}
static const char *a4 =
"After isc_task_shutdown() has been called, any call to "
"isc_task_onshutdown() will return ISC_R_SHUTTINGDOWN.";
static void
t4(void) {
if (threaded)
else
}
static int T7_nprobs;
static int T7_eflag;
static int T7_sdflag;
static isc_mutex_t T7_mx;
static isc_condition_t T7_cv;
static int T7_nfails;
static void
++T7_eflag;
}
static void
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_lock failed %s\n",
++T7_nprobs;
}
++T7_sdflag;
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_condition_signal failed %s\n",
++T7_nprobs;
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_unlock failed %s\n",
++T7_nprobs;
}
}
static int
t_tasks7(void) {
int result;
char *p;
unsigned int workers;
T7_nprobs = 0;
T7_nfails = 0;
T7_sdflag = 0;
T7_eflag = 0;
event_type = 7;
workers = 2;
p = t_getenv("ISC_TASK_WORKERS");
if (p != NULL)
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mem_create failed %s\n",
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_init failed %s\n",
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_condition_init failed %s\n",
DESTROYLOCK(&T7_mx);
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_taskmgr_create failed %s\n",
DESTROYLOCK(&T7_mx);
(void) isc_condition_destroy(&T7_cv);
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_lock failed %s\n",
DESTROYLOCK(&T7_mx);
(void) isc_condition_destroy(&T7_cv);
return(T_FAIL);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_task_create failed %s\n",
DESTROYLOCK(&T7_mx);
(void) isc_condition_destroy(&T7_cv);
return(T_FAIL);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_task_onshutdown returned %s\n",
DESTROYLOCK(&T7_mx);
(void) isc_condition_destroy(&T7_cv);
return(T_UNRESOLVED);
}
interval.nanoseconds = 0;
while (T7_sdflag == 0) {
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_time_nowplusinterval failed %s\n",
DESTROYLOCK(&T7_mx);
(void) isc_condition_destroy(&T7_cv);
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_condition_waituntil returned %s\n",
DESTROYLOCK(&T7_mx);
(void) isc_condition_destroy(&T7_cv);
return(T_FAIL);
}
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_unlock failed %s\n",
++T7_nprobs;
}
(void) isc_condition_destroy(&T7_cv);
DESTROYLOCK(&T7_mx);
if (T7_eflag == 0)
++T7_nfails;
if (T7_nfails != 0)
return(result);
}
static const char *a7 = "A call to isc_task_create() creates a task that can "
"receive events.";
static void
t7(void) {
if (threaded)
else
}
#define T10_SENDERCNT 3
#define T10_TYPECNT 4
#define T10_TAGCNT 5
#define T_CONTROL 99999
static int T10_nprobs;
static int T10_nfails;
static int T10_startflag;
static int T10_shutdownflag;
static int T10_eventcnt;
static isc_mutex_t T10_mx;
static isc_condition_t T10_cv;
static void *T10_purge_sender;
static isc_eventtype_t T10_purge_type_first;
static isc_eventtype_t T10_purge_type_last;
static void *T10_purge_tag;
static int T10_testrange;
static void
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_lock failed %s\n",
++T10_nprobs;
}
while (T10_startflag == 0) {
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_lock failed %s\n",
++T10_nprobs;
}
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_unlock failed %s\n",
++T10_nprobs;
}
}
static void
int sender_match;
int type_match;
int tag_match;
sender_match = 0;
type_match = 0;
tag_match = 0;
if (T_debug) {
t_info("Event %p,%d,%p,%s\n",
"NP" : "P");
}
if ((T10_purge_sender == NULL) ||
sender_match = 1;
}
if (T10_testrange == 0) {
type_match = 1;
}
} else {
type_match = 1;
}
}
if ((T10_purge_tag == NULL) ||
tag_match = 1;
}
t_info("event %p,%d,%p matched but was not purgable\n",
++T10_eventcnt;
} else {
t_info("*** event %p,%d,%p not purged\n",
}
} else {
++T10_eventcnt;
}
}
static void
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_lock failed %s\n",
++T10_nprobs;
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_condition_signal failed %s\n",
++T10_nprobs;
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_unlock failed %s\n",
++T10_nprobs;
}
}
static void
{
char *p;
unsigned int workers;
int sender_cnt;
int type_cnt;
int tag_cnt;
int event_cnt;
int cnt;
int nevents;
T10_startflag = 0;
T10_shutdownflag = 0;
T10_eventcnt = 0;
workers = 2;
p = t_getenv("ISC_TASK_WORKERS");
if (p != NULL)
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mem_create failed %s\n",
++*nprobs;
return;
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_init failed %s\n",
++*nprobs;
return;
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_condition_init failed %s\n",
++*nprobs;
return;
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_taskmgr_create failed %s\n",
(void) isc_condition_destroy(&T10_cv);
++*nprobs;
return;
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_task_create failed %s\n",
(void) isc_condition_destroy(&T10_cv);
++*nprobs;
return;
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_task_onshutdown returned %s\n",
(void) isc_condition_destroy(&T10_cv);
++*nprobs;
return;
}
/*
* Block the task on T10_cv.
*/
/*
* Fill the task's queue with some messages with varying
* sender, type, tag, and purgable attribute values.
*/
event_cnt = 0;
/*
* Make all odd message non-purgable.
*/
(tag_cnt %2))
++event_cnt;
}
}
}
if (T_debug)
if (testrange == 0) {
/*
* We're testing isc_task_purge.
*/
if (nevents != exp_nevents) {
t_info("*** isc_task_purge returned %d, expected %d\n",
++*nfails;
} else if (T_debug)
} else {
/*
* We're testing isc_task_purgerange.
*/
if (nevents != exp_nevents) {
t_info("*** isc_task_purgerange returned %d, "
++*nfails;
} else if (T_debug)
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_lock failed %s\n",
(void) isc_condition_destroy(&T10_cv);
++*nprobs;
return;
}
/*
* Unblock the task, allowing event processing.
*/
T10_startflag = 1;
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_condition_signal failed %s\n",
++*nprobs;
}
interval.nanoseconds = 0;
/*
* Wait for shutdown processing to complete.
*/
while (T10_shutdownflag == 0) {
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_time_nowplusinterval failed %s\n",
(void) isc_condition_destroy(&T10_cv);
++*nprobs;
return;
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_condition_waituntil returned %s\n",
(void) isc_condition_destroy(&T10_cv);
++*nfails;
return;
}
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_unlock failed %s\n",
++*nprobs;
}
(void) isc_condition_destroy(&T10_cv);
if (T_debug)
t_info("*** processed %d, purged %d, total %d\n",
++*nfails;
}
}
static int
t_tasks10(void) {
int result;
T10_nprobs = 0;
T10_nfails = 0;
/*
* Try purging on a specific sender.
*/
t_info("testing purge on 2,4,8 expecting 1\n");
&T10_nprobs, 0);
/*
* Try purging on all senders.
*/
t_info("testing purge on 0,4,8 expecting 3\n");
&T10_nprobs, 0);
/*
* Try purging on all senders, specified type, all tags.
*/
t_info("testing purge on 0,4,0 expecting 15\n");
&T10_nprobs, 0);
/*
* Try purging on a specified tag, no such type.
*/
t_info("testing purge on 0,99,8 expecting 0\n");
&T10_nprobs, 0);
/*
* Try purging on specified sender, type, all tags.
*/
t_info("testing purge on 0,5,0 expecting 5\n");
&T10_nprobs, 0);
if ((T10_nfails == 0) && (T10_nprobs == 0))
else if (T10_nfails != 0)
return(result);
}
static const char *a10 =
"A call to isc_task_purge(task, sender, type, tag) "
"purges all events of type 'type' and with tag 'tag' "
"not marked as unpurgable from sender from the task's "
"queue and returns the number of events purged.";
static void
t10(void) {
if (threaded)
else
}
static int T11_nprobs;
static int T11_nfails;
static int T11_startflag;
static int T11_shutdownflag;
static int T11_eventcnt;
static isc_mutex_t T11_mx;
static isc_condition_t T11_cv;
static void
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_lock failed %s\n",
++T11_nprobs;
}
while (T11_startflag == 0) {
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_lock failed %s\n",
++T11_nprobs;
}
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_unlock failed %s\n",
++T11_nprobs;
}
}
static void
++T11_eventcnt;
}
static void
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_lock failed %s\n",
++T11_nprobs;
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_condition_signal failed %s\n",
++T11_nprobs;
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_unlock failed %s\n",
++T11_nprobs;
}
}
static int
char *p;
unsigned int workers;
int result;
T11_startflag = 0;
T11_shutdownflag = 0;
T11_eventcnt = 0;
workers = 2;
p = t_getenv("ISC_TASK_WORKERS");
if (p != NULL)
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mem_create failed %s\n",
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_init failed %s\n",
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_condition_init failed %s\n",
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_taskmgr_create failed %s\n",
(void) isc_condition_destroy(&T11_cv);
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_task_create failed %s\n",
(void) isc_condition_destroy(&T11_cv);
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_task_onshutdown returned %s\n",
(void) isc_condition_destroy(&T11_cv);
return(T_UNRESOLVED);
}
/*
* Block the task on T11_cv.
*/
if (purgable)
else
t_info("isc_task_purgeevent returned %s, expected %s\n",
++T11_nfails;
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_lock failed %s\n",
++T11_nprobs;
}
/*
* Unblock the task, allowing event processing.
*/
T11_startflag = 1;
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_condition_signal failed %s\n",
++T11_nprobs;
}
interval.nanoseconds = 0;
/*
* Wait for shutdown processing to complete.
*/
while (T11_shutdownflag == 0) {
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_time_nowplusinterval failed %s\n",
++T11_nprobs;
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_condition_waituntil returned %s\n",
++T11_nprobs;
}
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mutex_unlock failed %s\n",
++T11_nprobs;
}
(void) isc_condition_destroy(&T11_cv);
t_info("Event was %s purged\n",
++T11_nfails;
}
if ((T11_nfails == 0) && (T11_nprobs == 0))
else if (T11_nfails)
return(result);
}
static const char *a11 =
"When the event is marked as purgable, a call to "
"isc_task_purgeevent(task, event) purges the event 'event' "
"from the task's queue and returns ISC_TRUE.";
static void
t11(void) {
if (threaded)
else
}
static const char *a12 =
"When the event is not marked as purgable, a call to "
"isc_task_purgeevent(task, event) does not purge the "
"event 'event' from the task's queue and returns "
"ISC_FALSE.";
static int
t_tasks12(void) {
return(t_tasks11(0));
}
static void
t12(void) {
if (threaded)
else
}
static int T13_nfails;
static int T13_nprobs;
static const char *a13 =
"A call to "
"isc_event_purgerange(task, sender, first, last, tag) "
"purges all events not marked unpurgable from "
"sender 'sender' and of type within the range 'first' "
"to 'last' inclusive from the task's event queue and "
"returns the number of tasks purged.";
static int
t_tasks13(void) {
int result;
T13_nfails = 0;
T13_nprobs = 0;
/*
* First let's try the same cases we used in t10.
*/
/*
* Try purging on a specific sender.
*/
t_info("testing purge on 2,4,8 expecting 1\n");
/*
* Try purging on all senders.
*/
t_info("testing purge on 0,4,8 expecting 3\n");
/*
* Try purging on all senders, specified type, all tags.
*/
t_info("testing purge on 0,4,0 expecting 15\n");
/*
* Try purging on a specified tag, no such type.
*/
t_info("testing purge on 0,99,8 expecting 0\n");
/*
* Try purging on specified sender, type, all tags.
*/
t_info("testing purge on 3,5,0 expecting 5\n");
/*
* Now let's try some ranges.
*/
t_info("testing purgerange on 2,4-5,8 expecting 2\n");
/*
* Try purging on all senders.
*/
t_info("testing purge on 0,4-5,8 expecting 5\n");
/*
* Try purging on all senders, specified type, all tags.
*/
t_info("testing purge on 0,5-6,0 expecting 28\n");
/*
* Try purging on a specified tag, no such type.
*/
t_info("testing purge on 0,99-101,8 expecting 0\n");
/*
* Try purging on specified sender, type, all tags.
*/
t_info("testing purge on 3,5-6,0 expecting 10\n");
&T13_nprobs, 1);
if ((T13_nfails == 0) && (T13_nprobs == 0))
else if (T13_nfails)
return (result);
}
static void
t13(void) {
if (threaded)
else
}
#define T14_NTASKS 10
#define T14_EXCLTASK 6
int t14_exclusiveerror = ISC_R_SUCCESS;
int t14_error = 0;
int t14_done = 0;
int spin(int n);
int t14_active[T14_NTASKS];
static void
if (taskno == T14_EXCLTASK) {
int i;
if (t14_exclusiveerror == ISC_R_SUCCESS)
else
t_info("task %d failed to got exclusive access: %d\n",
for (i = 0; i < T14_NTASKS; i++) {
if (t14_active[i])
t14_error++;
}
t14_done = 1;
} else {
t14_active[taskno]++;
(void) spin(10000000);
t14_active[taskno]--;
}
if (t14_done) {
} else {
}
}
int spin(int n) {
int i;
int r = 0;
for (i = 0; i < n; i++) {
r += i;
if (r > 1000000)
r = 0;
}
return (r);
}
static int
t_tasks14(void) {
char *p;
unsigned int workers;
int i;
for (i = 0; i < T14_NTASKS; i++)
workers = 4;
p = t_getenv("ISC_TASK_WORKERS");
if (p != NULL)
if (workers < 1) {
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
return(T_FAIL);
}
for (i = 0; i < T14_NTASKS; i++) {
int *v;
if (isc_result != ISC_R_SUCCESS) {
return(T_FAIL);
}
v = isc_mem_get(mctx, sizeof *v);
if (v == NULL) {
isc_task_detach(&tasks[i]);
t_info("isc_mem_get failed\n");
return(T_FAIL);
}
*v = i;
v, sizeof(*event));
isc_mem_put(mctx, v, sizeof *v);
t_info("isc_event_allocate failed\n");
return(T_UNRESOLVED);
}
}
for (i = 0; i < T14_NTASKS; i++) {
isc_task_detach(&tasks[i]);
}
if (t14_exclusiveerror != ISC_R_SUCCESS)
t_info("isc_task_beginexclusive() failed\n");
if (t14_error)
t_info("mutual access occurred\n");
return(T_FAIL);
}
return(T_PASS);
}
static void
t14(void) {
int result;
"isc_task_beginexclusive() gets exclusive access");
}
testspec_t T_testlist[] = {
{ t1, "basic task subsystem" },
{ t2, "maxtasks" },
{ t3, "isc_task_shutdown" },
{ t4, "isc_task_shutdown" },
{ t7, "isc_task_create" },
{ t10, "isc_task_purge" },
{ t11, "isc_task_purgeevent" },
{ t12, "isc_task_purgeevent" },
{ t13, "isc_task_purgerange" },
{ t14, "isc_task_beginexclusive" },
};