Annotation of libaitsched/src/tasks.c, revision 1.8.2.3
1.1 misho 1: /*************************************************************************
2: * (C) 2011 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
3: * by Michael Pounov <misho@openbsd-bg.org>
4: *
5: * $Author: misho $
1.8.2.3 ! misho 6: * $Id: tasks.c,v 1.8.2.2 2012/05/31 14:45:10 misho Exp $
1.1 misho 7: *
8: **************************************************************************
9: The ELWIX and AITNET software is distributed under the following
10: terms:
11:
12: All of the documentation and software included in the ELWIX and AITNET
13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
14:
1.6 misho 15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
1.1 misho 16: by Michael Pounov <misho@elwix.org>. All rights reserved.
17:
18: Redistribution and use in source and binary forms, with or without
19: modification, are permitted provided that the following conditions
20: are met:
21: 1. Redistributions of source code must retain the above copyright
22: notice, this list of conditions and the following disclaimer.
23: 2. Redistributions in binary form must reproduce the above copyright
24: notice, this list of conditions and the following disclaimer in the
25: documentation and/or other materials provided with the distribution.
26: 3. All advertising materials mentioning features or use of this software
27: must display the following acknowledgement:
28: This product includes software developed by Michael Pounov <misho@elwix.org>
29: ELWIX - Embedded LightWeight unIX and its contributors.
30: 4. Neither the name of AITNET nor the names of its contributors
31: may be used to endorse or promote products derived from this software
32: without specific prior written permission.
33:
34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37: ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44: SUCH DAMAGE.
45: */
46: #include "global.h"
47:
48:
1.4 misho 49: #pragma GCC visibility push(hidden)
50:
51: inline sched_task_t *
52: _sched_useTask(sched_root_task_t * __restrict root)
53: {
1.7 misho 54: sched_task_t *task, *tmp;
1.4 misho 55:
1.7 misho 56: TAILQ_FOREACH_SAFE(task, &root->root_unuse, task_node, tmp) {
1.4 misho 57: if (!TASK_ISLOCKED(task)) {
1.5 misho 58: #ifdef HAVE_LIBPTHREAD
59: pthread_mutex_lock(&root->root_mtx[taskUNUSE]);
60: #endif
1.4 misho 61: TAILQ_REMOVE(&root->root_unuse, task, task_node);
1.5 misho 62: #ifdef HAVE_LIBPTHREAD
63: pthread_mutex_unlock(&root->root_mtx[taskUNUSE]);
64: #endif
1.4 misho 65: break;
66: }
67: }
68:
69: if (!task) {
70: task = malloc(sizeof(sched_task_t));
71: if (!task) {
72: LOGERR;
73: return NULL;
74: }
75: }
76:
1.8.2.3 ! misho 77: memset(task, 0, sizeof(sched_task_t));
! 78: task->task_id = (uintptr_t) task;
1.4 misho 79: return task;
80: }
81:
82: inline sched_task_t *
83: _sched_unuseTask(sched_task_t * __restrict task)
84: {
85: TASK_UNLOCK(task);
1.5 misho 86: TASK_TYPE(task) = taskUNUSE;
87: #ifdef HAVE_LIBPTHREAD
88: pthread_mutex_lock(&TASK_ROOT(task)->root_mtx[taskUNUSE]);
89: #endif
1.8.2.3 ! misho 90: TAILQ_INSERT_TAIL(&TASK_ROOT(task)->root_unuse, TASK_ID(task), task_node);
1.5 misho 91: #ifdef HAVE_LIBPTHREAD
92: pthread_mutex_unlock(&TASK_ROOT(task)->root_mtx[taskUNUSE]);
93: #endif
1.4 misho 94: task = NULL;
95:
96: return task;
97: }
98:
99: #pragma GCC visibility pop
100:
101:
1.1 misho 102: /*
1.2 misho 103: * schedRead() - Add READ I/O task to scheduler queue
1.6 misho 104: *
1.1 misho 105: * @root = root task
106: * @func = task execution function
107: * @arg = 1st func argument
1.2 misho 108: * @fd = fd handle
1.5 misho 109: * @opt_data = Optional data
110: * @opt_dlen = Optional data length
1.1 misho 111: * return: NULL error or !=NULL new queued task
112: */
113: sched_task_t *
1.5 misho 114: schedRead(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, int fd,
115: void *opt_data, size_t opt_dlen)
1.1 misho 116: {
117: sched_task_t *task;
118: void *ptr;
119:
120: if (!root || !func)
121: return NULL;
122:
123: /* get new task */
1.4 misho 124: if (!(task = _sched_useTask(root)))
125: return NULL;
1.1 misho 126:
127: task->task_func = func;
1.5 misho 128: TASK_TYPE(task) = taskREAD;
129: TASK_ROOT(task) = root;
1.1 misho 130:
131: TASK_ARG(task) = arg;
1.2 misho 132: TASK_FD(task) = fd;
1.1 misho 133:
1.5 misho 134: TASK_DATA(task) = opt_data;
135: TASK_DATLEN(task) = opt_dlen;
136:
1.1 misho 137: if (root->root_hooks.hook_add.read)
138: ptr = root->root_hooks.hook_add.read(task, NULL);
139: else
140: ptr = NULL;
141:
1.5 misho 142: if (!ptr) {
143: #ifdef HAVE_LIBPTHREAD
144: pthread_mutex_lock(&root->root_mtx[taskREAD]);
145: #endif
1.8.2.3 ! misho 146: TAILQ_INSERT_TAIL(&root->root_read, TASK_ID(task), task_node);
1.5 misho 147: #ifdef HAVE_LIBPTHREAD
148: pthread_mutex_unlock(&root->root_mtx[taskREAD]);
149: #endif
150: } else
1.4 misho 151: task = _sched_unuseTask(task);
1.1 misho 152:
153: return task;
154: }
155:
156: /*
1.2 misho 157: * schedWrite() - Add WRITE I/O task to scheduler queue
1.6 misho 158: *
1.1 misho 159: * @root = root task
160: * @func = task execution function
161: * @arg = 1st func argument
1.2 misho 162: * @fd = fd handle
1.5 misho 163: * @opt_data = Optional data
164: * @opt_dlen = Optional data length
1.1 misho 165: * return: NULL error or !=NULL new queued task
166: */
167: sched_task_t *
1.5 misho 168: schedWrite(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, int fd,
169: void *opt_data, size_t opt_dlen)
1.1 misho 170: {
171: sched_task_t *task;
172: void *ptr;
173:
174: if (!root || !func)
175: return NULL;
176:
177: /* get new task */
1.4 misho 178: if (!(task = _sched_useTask(root)))
179: return NULL;
1.1 misho 180:
181: task->task_func = func;
1.5 misho 182: TASK_TYPE(task) = taskWRITE;
183: TASK_ROOT(task) = root;
1.1 misho 184:
185: TASK_ARG(task) = arg;
1.2 misho 186: TASK_FD(task) = fd;
1.1 misho 187:
1.5 misho 188: TASK_DATA(task) = opt_data;
189: TASK_DATLEN(task) = opt_dlen;
190:
1.1 misho 191: if (root->root_hooks.hook_add.write)
192: ptr = root->root_hooks.hook_add.write(task, NULL);
193: else
194: ptr = NULL;
195:
1.5 misho 196: if (!ptr) {
197: #ifdef HAVE_LIBPTHREAD
198: pthread_mutex_lock(&root->root_mtx[taskWRITE]);
199: #endif
1.8.2.3 ! misho 200: TAILQ_INSERT_TAIL(&root->root_write, TASK_ID(task), task_node);
1.5 misho 201: #ifdef HAVE_LIBPTHREAD
202: pthread_mutex_unlock(&root->root_mtx[taskWRITE]);
203: #endif
204: } else
1.4 misho 205: task = _sched_unuseTask(task);
1.1 misho 206:
207: return task;
208: }
209:
210: /*
1.8.2.1 misho 211: * schedNode() - Add NODE task to scheduler queue
212: *
213: * @root = root task
214: * @func = task execution function
215: * @arg = 1st func argument
216: * @fd = fd handle
217: * @opt_data = Optional data
218: * @opt_dlen = Optional data length
219: * return: NULL error or !=NULL new queued task
220: */
221: sched_task_t *
222: schedNode(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, int fd,
223: void *opt_data, size_t opt_dlen)
224: {
225: sched_task_t *task;
226: void *ptr;
227:
228: if (!root || !func)
229: return NULL;
230:
231: /* get new task */
232: if (!(task = _sched_useTask(root)))
233: return NULL;
234:
235: task->task_func = func;
236: TASK_TYPE(task) = taskNODE;
237: TASK_ROOT(task) = root;
238:
239: TASK_ARG(task) = arg;
240: TASK_FD(task) = fd;
241:
242: TASK_DATA(task) = opt_data;
243: TASK_DATLEN(task) = opt_dlen;
244:
245: if (root->root_hooks.hook_add.node)
246: ptr = root->root_hooks.hook_add.node(task, NULL);
247: else
248: ptr = NULL;
249:
250: if (!ptr) {
251: #ifdef HAVE_LIBPTHREAD
252: pthread_mutex_lock(&root->root_mtx[taskNODE]);
253: #endif
1.8.2.3 ! misho 254: TAILQ_INSERT_TAIL(&root->root_node, TASK_ID(task), task_node);
1.8.2.1 misho 255: #ifdef HAVE_LIBPTHREAD
256: pthread_mutex_unlock(&root->root_mtx[taskNODE]);
257: #endif
258: } else
259: task = _sched_unuseTask(task);
260:
261: return task;
262: }
263:
264: /*
265: * schedProc() - Add PROC task to scheduler queue
266: *
267: * @root = root task
268: * @func = task execution function
269: * @arg = 1st func argument
270: * @pid = PID
271: * @opt_data = Optional data
272: * @opt_dlen = Optional data length
273: * return: NULL error or !=NULL new queued task
274: */
275: sched_task_t *
276: schedProc(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, u_long pid,
277: void *opt_data, size_t opt_dlen)
278: {
279: sched_task_t *task;
280: void *ptr;
281:
282: if (!root || !func)
283: return NULL;
284:
285: /* get new task */
286: if (!(task = _sched_useTask(root)))
287: return NULL;
288:
289: task->task_func = func;
290: TASK_TYPE(task) = taskPROC;
291: TASK_ROOT(task) = root;
292:
293: TASK_ARG(task) = arg;
294: TASK_VAL(task) = pid;
295:
296: TASK_DATA(task) = opt_data;
297: TASK_DATLEN(task) = opt_dlen;
298:
299: if (root->root_hooks.hook_add.proc)
300: ptr = root->root_hooks.hook_add.proc(task, NULL);
301: else
302: ptr = NULL;
303:
304: if (!ptr) {
305: #ifdef HAVE_LIBPTHREAD
306: pthread_mutex_lock(&root->root_mtx[taskPROC]);
307: #endif
1.8.2.3 ! misho 308: TAILQ_INSERT_TAIL(&root->root_proc, TASK_ID(task), task_node);
1.8.2.1 misho 309: #ifdef HAVE_LIBPTHREAD
310: pthread_mutex_unlock(&root->root_mtx[taskPROC]);
311: #endif
312: } else
313: task = _sched_unuseTask(task);
314:
315: return task;
316: }
317:
318: /*
319: * schedUser() - Add trigger USER task to scheduler queue
320: *
321: * @root = root task
322: * @func = task execution function
323: * @arg = 1st func argument
324: * @id = Trigger ID
325: * @opt_data = Optional data
1.8.2.2 misho 326: * @opt_dlen = Optional user's trigger flags
1.8.2.1 misho 327: * return: NULL error or !=NULL new queued task
328: */
329: sched_task_t *
330: schedUser(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, u_long id,
331: void *opt_data, size_t opt_dlen)
332: {
333: sched_task_t *task;
334: void *ptr;
335:
336: if (!root || !func)
337: return NULL;
338:
339: /* get new task */
340: if (!(task = _sched_useTask(root)))
341: return NULL;
342:
343: task->task_func = func;
344: TASK_TYPE(task) = taskUSER;
345: TASK_ROOT(task) = root;
346:
347: TASK_ARG(task) = arg;
348: TASK_VAL(task) = id;
349:
350: TASK_DATA(task) = opt_data;
351: TASK_DATLEN(task) = opt_dlen;
352:
353: if (root->root_hooks.hook_add.user)
354: ptr = root->root_hooks.hook_add.user(task, NULL);
355: else
356: ptr = NULL;
357:
358: if (!ptr) {
359: #ifdef HAVE_LIBPTHREAD
360: pthread_mutex_lock(&root->root_mtx[taskUSER]);
361: #endif
1.8.2.3 ! misho 362: TAILQ_INSERT_TAIL(&root->root_user, TASK_ID(task), task_node);
1.8.2.1 misho 363: #ifdef HAVE_LIBPTHREAD
364: pthread_mutex_unlock(&root->root_mtx[taskUSER]);
365: #endif
366: } else
367: task = _sched_unuseTask(task);
368:
369: return task;
370: }
371:
372: /*
373: * schedSignal() - Add SIGNAL task to scheduler queue
374: *
375: * @root = root task
376: * @func = task execution function
377: * @arg = 1st func argument
378: * @sig = Signal
379: * @opt_data = Optional data
380: * @opt_dlen = Optional data length
381: * return: NULL error or !=NULL new queued task
382: */
383: sched_task_t *
384: schedSignal(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, u_long sig,
385: void *opt_data, size_t opt_dlen)
386: {
387: sched_task_t *task;
388: void *ptr;
389:
390: if (!root || !func)
391: return NULL;
392:
393: /* get new task */
394: if (!(task = _sched_useTask(root)))
395: return NULL;
396:
397: task->task_func = func;
398: TASK_TYPE(task) = taskSIGNAL;
399: TASK_ROOT(task) = root;
400:
401: TASK_ARG(task) = arg;
402: TASK_VAL(task) = sig;
403:
404: TASK_DATA(task) = opt_data;
405: TASK_DATLEN(task) = opt_dlen;
406:
407: if (root->root_hooks.hook_add.signal)
408: ptr = root->root_hooks.hook_add.signal(task, NULL);
409: else
410: ptr = NULL;
411:
412: if (!ptr) {
413: #ifdef HAVE_LIBPTHREAD
414: pthread_mutex_lock(&root->root_mtx[taskSIGNAL]);
415: #endif
1.8.2.3 ! misho 416: TAILQ_INSERT_TAIL(&root->root_signal, TASK_ID(task), task_node);
1.8.2.1 misho 417: #ifdef HAVE_LIBPTHREAD
418: pthread_mutex_unlock(&root->root_mtx[taskSIGNAL]);
419: #endif
420: } else
421: task = _sched_unuseTask(task);
422:
423: return task;
424: }
425:
426: /*
1.8 misho 427: * schedAlarm() - Add ALARM task to scheduler queue
428: *
429: * @root = root task
430: * @func = task execution function
431: * @arg = 1st func argument
432: * @ts = timeout argument structure, minimum alarm timer resolution is 1msec!
433: * @opt_data = Optional data
434: * @opt_dlen = Optional data length
435: * return: NULL error or !=NULL new queued task
436: */
437: sched_task_t *
438: schedAlarm(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, struct timespec ts,
439: void *opt_data, size_t opt_dlen)
440: {
441: sched_task_t *task;
442: void *ptr;
443:
444: if (!root || !func)
445: return NULL;
446:
447: /* get new task */
448: if (!(task = _sched_useTask(root)))
449: return NULL;
450:
451: task->task_func = func;
452: TASK_TYPE(task) = taskALARM;
453: TASK_ROOT(task) = root;
454:
455: TASK_ARG(task) = arg;
456: TASK_TS(task) = ts;
457:
458: TASK_DATA(task) = opt_data;
459: TASK_DATLEN(task) = opt_dlen;
460:
461: if (root->root_hooks.hook_add.alarm)
462: ptr = root->root_hooks.hook_add.alarm(task, NULL);
463: else
464: ptr = NULL;
465:
466: if (!ptr) {
467: #ifdef HAVE_LIBPTHREAD
468: pthread_mutex_lock(&root->root_mtx[taskALARM]);
469: #endif
1.8.2.3 ! misho 470: TAILQ_INSERT_TAIL(&root->root_alarm, TASK_ID(task), task_node);
1.8 misho 471: #ifdef HAVE_LIBPTHREAD
472: pthread_mutex_unlock(&root->root_mtx[taskALARM]);
473: #endif
474: } else
475: task = _sched_unuseTask(task);
476:
477: return task;
478: }
479:
480: /*
1.1 misho 481: * schedTimer() - Add TIMER task to scheduler queue
1.6 misho 482: *
1.1 misho 483: * @root = root task
484: * @func = task execution function
485: * @arg = 1st func argument
1.5 misho 486: * @ts = timeout argument structure
487: * @opt_data = Optional data
488: * @opt_dlen = Optional data length
1.1 misho 489: * return: NULL error or !=NULL new queued task
490: */
491: sched_task_t *
1.5 misho 492: schedTimer(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, struct timespec ts,
493: void *opt_data, size_t opt_dlen)
1.1 misho 494: {
1.8.2.3 ! misho 495: sched_task_t *task, *tmp, *t = NULL;
1.1 misho 496: void *ptr;
1.5 misho 497: struct timespec now;
1.1 misho 498:
499: if (!root || !func)
500: return NULL;
501:
502: /* get new task */
1.4 misho 503: if (!(task = _sched_useTask(root)))
504: return NULL;
1.1 misho 505:
506: task->task_func = func;
1.5 misho 507: TASK_TYPE(task) = taskTIMER;
508: TASK_ROOT(task) = root;
1.1 misho 509:
510: TASK_ARG(task) = arg;
511:
1.5 misho 512: TASK_DATA(task) = opt_data;
513: TASK_DATLEN(task) = opt_dlen;
514:
1.1 misho 515: /* calculate timeval structure */
1.5 misho 516: clock_gettime(CLOCK_MONOTONIC, &now);
517: now.tv_sec += ts.tv_sec;
518: now.tv_nsec += ts.tv_nsec;
519: if (now.tv_nsec >= 1000000000L) {
1.1 misho 520: now.tv_sec++;
1.5 misho 521: now.tv_nsec -= 1000000000L;
522: } else if (now.tv_nsec < 0) {
1.1 misho 523: now.tv_sec--;
1.5 misho 524: now.tv_nsec += 1000000000L;
1.1 misho 525: }
1.5 misho 526: TASK_TS(task) = now;
1.1 misho 527:
528: if (root->root_hooks.hook_add.timer)
529: ptr = root->root_hooks.hook_add.timer(task, NULL);
530: else
531: ptr = NULL;
532:
533: if (!ptr) {
1.5 misho 534: #ifdef HAVE_LIBPTHREAD
535: pthread_mutex_lock(&root->root_mtx[taskTIMER]);
536: #endif
1.1 misho 537: #ifdef TIMER_WITHOUT_SORT
1.8.2.3 ! misho 538: TAILQ_INSERT_TAIL(&root->root_timer, TASK_ID(task), task_node);
1.1 misho 539: #else
1.8.2.3 ! misho 540: TAILQ_FOREACH_SAFE(t, &root->root_timer, task_node, tmp)
1.5 misho 541: if (sched_timespeccmp(&TASK_TS(task), &TASK_TS(t), -) < 1)
1.1 misho 542: break;
543: if (!t)
1.8.2.3 ! misho 544: TAILQ_INSERT_TAIL(&root->root_timer, TASK_ID(task), task_node);
1.1 misho 545: else
1.8.2.3 ! misho 546: TAILQ_INSERT_BEFORE(t, TASK_ID(task), task_node);
1.1 misho 547: #endif
1.5 misho 548: #ifdef HAVE_LIBPTHREAD
549: pthread_mutex_unlock(&root->root_mtx[taskTIMER]);
550: #endif
1.4 misho 551: } else
552: task = _sched_unuseTask(task);
1.1 misho 553:
554: return task;
555: }
556:
557: /*
558: * schedEvent() - Add EVENT task to scheduler queue
1.6 misho 559: *
1.1 misho 560: * @root = root task
561: * @func = task execution function
562: * @arg = 1st func argument
1.2 misho 563: * @val = additional func argument
1.5 misho 564: * @opt_data = Optional data
565: * @opt_dlen = Optional data length
1.1 misho 566: * return: NULL error or !=NULL new queued task
567: */
568: sched_task_t *
1.5 misho 569: schedEvent(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, u_long val,
570: void *opt_data, size_t opt_dlen)
1.1 misho 571: {
572: sched_task_t *task;
573: void *ptr;
574:
575: if (!root || !func)
576: return NULL;
577:
578: /* get new task */
1.4 misho 579: if (!(task = _sched_useTask(root)))
580: return NULL;
1.1 misho 581:
582: task->task_func = func;
1.5 misho 583: TASK_TYPE(task) = taskEVENT;
584: TASK_ROOT(task) = root;
1.1 misho 585:
586: TASK_ARG(task) = arg;
1.2 misho 587: TASK_VAL(task) = val;
1.1 misho 588:
1.5 misho 589: TASK_DATA(task) = opt_data;
590: TASK_DATLEN(task) = opt_dlen;
591:
1.1 misho 592: if (root->root_hooks.hook_add.event)
593: ptr = root->root_hooks.hook_add.event(task, NULL);
594: else
595: ptr = NULL;
596:
1.5 misho 597: if (!ptr) {
598: #ifdef HAVE_LIBPTHREAD
599: pthread_mutex_lock(&root->root_mtx[taskEVENT]);
600: #endif
1.8.2.3 ! misho 601: TAILQ_INSERT_TAIL(&root->root_event, TASK_ID(task), task_node);
1.5 misho 602: #ifdef HAVE_LIBPTHREAD
603: pthread_mutex_unlock(&root->root_mtx[taskEVENT]);
604: #endif
605: } else
1.4 misho 606: task = _sched_unuseTask(task);
1.1 misho 607:
608: return task;
609: }
610:
611:
612: /*
613: * schedEventLo() - Add EVENT_Lo task to scheduler queue
1.6 misho 614: *
1.1 misho 615: * @root = root task
616: * @func = task execution function
617: * @arg = 1st func argument
1.2 misho 618: * @val = additional func argument
1.5 misho 619: * @opt_data = Optional data
620: * @opt_dlen = Optional data length
1.1 misho 621: * return: NULL error or !=NULL new queued task
622: */
623: sched_task_t *
1.5 misho 624: schedEventLo(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, u_long val,
625: void *opt_data, size_t opt_dlen)
1.1 misho 626: {
627: sched_task_t *task;
628: void *ptr;
629:
630: if (!root || !func)
631: return NULL;
632:
633: /* get new task */
1.4 misho 634: if (!(task = _sched_useTask(root)))
635: return NULL;
1.1 misho 636:
637: task->task_func = func;
1.5 misho 638: TASK_TYPE(task) = taskEVENT;
639: TASK_ROOT(task) = root;
1.1 misho 640:
641: TASK_ARG(task) = arg;
1.2 misho 642: TASK_VAL(task) = val;
1.1 misho 643:
1.5 misho 644: TASK_DATA(task) = opt_data;
645: TASK_DATLEN(task) = opt_dlen;
646:
1.1 misho 647: if (root->root_hooks.hook_add.eventlo)
648: ptr = root->root_hooks.hook_add.eventlo(task, NULL);
649: else
650: ptr = NULL;
651:
1.5 misho 652: if (!ptr) {
653: #ifdef HAVE_LIBPTHREAD
654: pthread_mutex_lock(&root->root_mtx[taskEVENTLO]);
655: #endif
1.8.2.3 ! misho 656: TAILQ_INSERT_TAIL(&root->root_eventlo, TASK_ID(task), task_node);
1.5 misho 657: #ifdef HAVE_LIBPTHREAD
658: pthread_mutex_unlock(&root->root_mtx[taskEVENTLO]);
659: #endif
660: } else
1.4 misho 661: task = _sched_unuseTask(task);
1.1 misho 662:
663: return task;
664: }
665:
666: /*
667: * schedCallOnce() - Call once from scheduler
1.6 misho 668: *
1.1 misho 669: * @root = root task
670: * @func = task execution function
671: * @arg = 1st func argument
1.2 misho 672: * @val = additional func argument
1.5 misho 673: * @opt_data = Optional data
674: * @opt_dlen = Optional data length
1.2 misho 675: * return: return value from called func
1.1 misho 676: */
677: sched_task_t *
1.5 misho 678: schedCallOnce(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, u_long val,
679: void *opt_data, size_t opt_dlen)
1.1 misho 680: {
681: sched_task_t *task;
1.2 misho 682: void *ret;
1.1 misho 683:
684: if (!root || !func)
685: return NULL;
686:
687: /* get new task */
1.4 misho 688: if (!(task = _sched_useTask(root)))
689: return NULL;
1.1 misho 690:
691: task->task_func = func;
1.5 misho 692: TASK_TYPE(task) = taskEVENT;
693: TASK_ROOT(task) = root;
1.1 misho 694:
695: TASK_ARG(task) = arg;
1.2 misho 696: TASK_VAL(task) = val;
1.1 misho 697:
1.5 misho 698: TASK_DATA(task) = opt_data;
699: TASK_DATLEN(task) = opt_dlen;
700:
1.2 misho 701: ret = schedCall(task);
1.1 misho 702:
1.4 misho 703: _sched_unuseTask(task);
1.2 misho 704: return ret;
1.1 misho 705: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>