📄 t_tasks.c
字号:
t_result(t_tasks10()); else require_threads();}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 voidt11_event1(isc_task_t *task, isc_event_t *event) { isc_result_t isc_result; task = task; isc_result = isc_mutex_lock(&T11_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_lock failed %s\n", isc_result_totext(isc_result)); ++T11_nprobs; } while (T11_startflag == 0) { isc_result = isc_condition_wait(&T11_cv, &T11_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_lock failed %s\n", isc_result_totext(isc_result)); ++T11_nprobs; } } isc_result = isc_mutex_unlock(&T11_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_unlock failed %s\n", isc_result_totext(isc_result)); ++T11_nprobs; } isc_event_free(&event);}static voidt11_event2(isc_task_t *task, isc_event_t *event) { UNUSED(task); ++T11_eventcnt; isc_event_free(&event);}static voidt11_sde(isc_task_t *task, isc_event_t *event) { isc_result_t isc_result; UNUSED(task); isc_result = isc_mutex_lock(&T11_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_lock failed %s\n", isc_result_totext(isc_result)); ++T11_nprobs; } ++T11_shutdownflag; isc_result = isc_condition_signal(&T11_cv); if (isc_result != ISC_R_SUCCESS) { t_info("isc_condition_signal failed %s\n", isc_result_totext(isc_result)); ++T11_nprobs; } isc_result = isc_mutex_unlock(&T11_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_unlock failed %s\n", isc_result_totext(isc_result)); ++T11_nprobs; } isc_event_free(&event);}static intt_tasks11(int purgable) { char *p; isc_mem_t *mctx; isc_taskmgr_t *tmgr; isc_task_t *task; isc_boolean_t rval; unsigned int workers; isc_result_t isc_result; isc_event_t *event1; isc_event_t *event2, *event2_clone; isc_time_t now; isc_interval_t interval; int result; T11_startflag = 0; T11_shutdownflag = 0; T11_eventcnt = 0; workers = 2; p = t_getenv("ISC_TASK_WORKERS"); if (p != NULL) workers = atoi(p); mctx = NULL; isc_result = isc_mem_create(0, 0, &mctx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mem_create failed %s\n", isc_result_totext(isc_result)); return(T_UNRESOLVED); } isc_result = isc_mutex_init(&T11_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_init failed %s\n", isc_result_totext(isc_result)); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } isc_result = isc_condition_init(&T11_cv); if (isc_result != ISC_R_SUCCESS) { t_info("isc_condition_init failed %s\n", isc_result_totext(isc_result)); isc_mem_destroy(&mctx); DESTROYLOCK(&T11_mx); return(T_UNRESOLVED); } tmgr = NULL; isc_result = isc_taskmgr_create(mctx, workers, 0, &tmgr); if (isc_result != ISC_R_SUCCESS) { t_info("isc_taskmgr_create failed %s\n", isc_result_totext(isc_result)); isc_mem_destroy(&mctx); DESTROYLOCK(&T11_mx); isc_condition_destroy(&T11_cv); return(T_UNRESOLVED); } task = NULL; isc_result = isc_task_create(tmgr, 0, &task); if (isc_result != ISC_R_SUCCESS) { t_info("isc_task_create failed %s\n", isc_result_totext(isc_result)); isc_taskmgr_destroy(&tmgr); isc_mem_destroy(&mctx); DESTROYLOCK(&T11_mx); isc_condition_destroy(&T11_cv); return(T_UNRESOLVED); } isc_result = isc_task_onshutdown(task, t11_sde, NULL); if (isc_result != ISC_R_SUCCESS) { t_info("isc_task_onshutdown returned %s\n", isc_result_totext(isc_result)); isc_task_destroy(&task); isc_taskmgr_destroy(&tmgr); isc_mem_destroy(&mctx); DESTROYLOCK(&T11_mx); isc_condition_destroy(&T11_cv); return(T_UNRESOLVED); } /* * Block the task on T11_cv. */ event1 = isc_event_allocate(mctx, (void *)1, (isc_eventtype_t)1, t11_event1, NULL, sizeof(*event1)); isc_task_send(task, &event1); event2 = isc_event_allocate(mctx, (void *)1, (isc_eventtype_t)1, t11_event2, NULL, sizeof(*event2)); event2_clone = event2; if (purgable) event2->ev_attributes &= ~ISC_EVENTATTR_NOPURGE; else event2->ev_attributes |= ISC_EVENTATTR_NOPURGE; isc_task_send(task, &event2); rval = isc_task_purgeevent(task, event2_clone); if (rval != (purgable ? ISC_TRUE : ISC_FALSE)) { t_info("isc_task_purgeevent returned %s, expected %s\n", (rval ? "ISC_TRUE" : "ISC_FALSE"), (purgable ? "ISC_TRUE" : "ISC_FALSE")); ++T11_nfails; } isc_result = isc_mutex_lock(&T11_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_lock failed %s\n", isc_result_totext(isc_result)); ++T11_nprobs; } /* * Unblock the task, allowing event processing. */ T11_startflag = 1; isc_result = isc_condition_signal(&T11_cv); if (isc_result != ISC_R_SUCCESS) { t_info("isc_condition_signal failed %s\n", isc_result_totext(isc_result)); ++T11_nprobs; } isc_task_shutdown(task); interval.seconds = 5; interval.nanoseconds = 0; /* * Wait for shutdown processing to complete. */ while (T11_shutdownflag == 0) { isc_result = isc_time_nowplusinterval(&now, &interval); if (isc_result != ISC_R_SUCCESS) { t_info("isc_time_nowplusinterval failed %s\n", isc_result_totext(isc_result)); ++T11_nprobs; } isc_result = isc_condition_waituntil(&T11_cv, &T11_mx, &now); if (isc_result != ISC_R_SUCCESS) { t_info("isc_condition_waituntil returned %s\n", isc_result_totext(isc_result)); ++T11_nprobs; } } isc_result = isc_mutex_unlock(&T11_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_unlock failed %s\n", isc_result_totext(isc_result)); ++T11_nprobs; } isc_task_detach(&task); isc_taskmgr_destroy(&tmgr); isc_mem_destroy(&mctx); DESTROYLOCK(&T11_mx); isc_condition_destroy(&T11_cv); if (T11_eventcnt != (purgable ? 0 : 1)) { t_info("Event was %s purged\n", (purgable ? "not" : "unexpectedly")); ++T11_nfails; } result = T_UNRESOLVED; if ((T11_nfails == 0) && (T11_nprobs == 0)) result = T_PASS; else if (T11_nfails) result = T_FAIL; 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 voidt11(void) { t_assert("tasks", 11, T_REQUIRED, a11); if (threaded) t_result(t_tasks11(1)); else require_threads();}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 intt_tasks12(void) { return(t_tasks11(0));}static voidt12(void) { t_assert("tasks", 12, T_REQUIRED, a12); if (threaded) t_result(t_tasks12()); else require_threads();}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 intt_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"); t_taskpurge_x(1, 4, 7, &senders[2], 4, 4, (void *)8, 1, &T13_nfails, &T13_nprobs, 1); /* * Try purging on all senders. */ t_info("testing purge on 0,4,8 expecting 3\n"); t_taskpurge_x(1, 4, 7, NULL, 4, 4, (void *)8, 3, &T13_nfails, &T13_nprobs, 1); /* * Try purging on all senders, specified type, all tags. */ t_info("testing purge on 0,4,0 expecting 15\n"); t_taskpurge_x(1, 4, 7, NULL, 4, 4, NULL, 15, &T13_nfails, &T13_nprobs, 1); /* * Try purging on a specified tag, no such type. */ t_info("testing purge on 0,99,8 expecting 0\n"); t_taskpurge_x(1, 4, 7, NULL, 99, 99, (void *)8, 0, &T13_nfails, &T13_nprobs, 1); /* * Try purging on specified sender, type, all tags. */ t_info("testing purge on 3,5,0 expecting 5\n"); t_taskpurge_x(1, 4, 7, &senders[3], 5, 5, 0, 5, &T13_nfails, &T13_nprobs, 1); /* * Now let's try some ranges. */ t_info("testing purgerange on 2,4-5,8 expecting 2\n"); t_taskpurge_x(1, 4, 7, &senders[2], 4, 5, (void *)8, 1, &T13_nfails, &T13_nprobs, 1); /* * Try purging on all senders. */ t_info("testing purge on 0,4-5,8 expecting 5\n"); t_taskpurge_x(1, 4, 7, NULL, 4, 5, (void *)8, 5, &T13_nfails, &T13_nprobs, 1); /* * Try purging on all senders, specified type, all tags. */ t_info("testing purge on 0,5-6,0 expecting 28\n"); t_taskpurge_x(1, 4, 7, NULL, 5, 6, NULL, 28, &T13_nfails, &T13_nprobs, 1); /* * Try purging on a specified tag, no such type. */ t_info("testing purge on 0,99-101,8 expecting 0\n"); t_taskpurge_x(1, 4, 7, NULL, 99, 101, (void *)8, 0, &T13_nfails, &T13_nprobs, 1); /* * Try purging on specified sender, type, all tags. */ t_info("testing purge on 3,5-6,0 expecting 10\n"); t_taskpurge_x(1, 4, 7, &senders[3], 5, 6, NULL, 10, &T13_nfails, &T13_nprobs, 1); result = T_UNRESOLVED; if ((T13_nfails == 0) && (T13_nprobs == 0)) result = T_PASS; else if (T13_nfails) result = T_FAIL; return (result);}static voidt13(void) { t_assert("tasks", 13, T_REQUIRED, a13); if (threaded) t_result(t_tasks13()); else require_threads();}#define T14_NTASKS 10#define T14_EXCLTASK 6int t14_error = 0;int t14_done = 0;int spin(int n);int t14_active[T14_NTASKS];static voidt14_callback(isc_task_t *task, isc_event_t *event) { int taskno = *(int *)(event->ev_arg); t_info("task enter %d\n", taskno); if (taskno == T14_EXCLTASK) { int i; isc_task_beginexclusive(task); t_info("task %d got exclusive access\n", taskno); for (i = 0; i < T14_NTASKS; i++) { t_info("task %d state %d\n", i , t14_active[i]); if (t14_active[i]) t14_error++; } isc_task_endexclusive(task); t14_done = 1; } else { t14_active[taskno]++; (void) spin(10000000); t14_active[taskno]--; } t_info("task exit %d\n", taskno); if (t14_done) { isc_mem_put(event->ev_destroy_arg, event->ev_arg, sizeof (int)); isc_event_free(&event); } else { isc_task_send(task, &event); }}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 intt_tasks14(void) { char *p; isc_mem_t *mctx; isc_taskmgr_t *manager; isc_task_t *tasks[T14_NTASKS]; unsigned int workers; isc_result_t isc_result; int i; manager = NULL; mctx = NULL; for (i = 0; i < T14_NTASKS; i++) tasks[i] = NULL; workers = 4; p = t_getenv("ISC_TASK_WORKERS"); if (p != NULL) workers = atoi(p); if (workers < 1) { t_info("Bad config value for ISC_TASK_WORKERS, %d\n", workers); return(T_UNRESOLVED); } isc_result = isc_mem_create(0, 0, &mctx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mem_create failed %d\n", isc_result); return(T_UNRESOLVED); } isc_result = isc_taskmgr_create(mctx, workers, 0, &manager); if (isc_result != ISC_R_SUCCESS) { t_info("isc_taskmgr_create failed %d\n", isc_result); return(T_FAIL); } for (i = 0; i < T14_NTASKS; i++) { isc_event_t *event; int *v; isc_result = isc_task_create(manager, 0, &tasks[i]); if (isc_result != ISC_R_SUCCESS) { t_info("isc_task_create failed %d\n", isc_result); 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; event = isc_event_allocate(mctx, NULL, 1, t14_callback, v, sizeof(*event)); if (event == NULL) { isc_mem_put(mctx, v, sizeof *v); t_info("isc_event_allocate failed\n"); return(T_UNRESOLVED); } isc_task_send(tasks[i], &event); } for (i = 0; i < T14_NTASKS; i++) { isc_task_detach(&tasks[i]); } isc_taskmgr_destroy(&manager); if (t14_error) { t_info("mutual access occurred\n"); return(T_FAIL); } isc_mem_destroy(&mctx); return(T_PASS);}static voidt14(void) { int result; t_assert("tasks", 14, T_REQUIRED, "isc_task_beginexclusive() gets exclusive access"); result = t_tasks14(); t_result(result);}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" }, { NULL, NULL }};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -