Annotation of libaitsched/src/tasks.c, revision 1.8.2.1
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.1 ! misho 6: * $Id: tasks.c,v 1.8 2012/05/30 08:52:45 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:
77: return task;
78: }
79:
80: inline sched_task_t *
81: _sched_unuseTask(sched_task_t * __restrict task)
82: {
83: TASK_UNLOCK(task);
1.5 misho 84: TASK_TYPE(task) = taskUNUSE;
85: #ifdef HAVE_LIBPTHREAD
86: pthread_mutex_lock(&TASK_ROOT(task)->root_mtx[taskUNUSE]);
87: #endif
88: TAILQ_INSERT_TAIL(&TASK_ROOT(task)->root_unuse, task, task_node);
89: #ifdef HAVE_LIBPTHREAD
90: pthread_mutex_unlock(&TASK_ROOT(task)->root_mtx[taskUNUSE]);
91: #endif
1.4 misho 92: task = NULL;
93:
94: return task;
95: }
96:
97: #pragma GCC visibility pop
98:
99:
1.1 misho 100: /*
1.2 misho 101: * schedRead() - Add READ I/O task to scheduler queue
1.6 misho 102: *
1.1 misho 103: * @root = root task
104: * @func = task execution function
105: * @arg = 1st func argument
1.2 misho 106: * @fd = fd handle
1.5 misho 107: * @opt_data = Optional data
108: * @opt_dlen = Optional data length
1.1 misho 109: * return: NULL error or !=NULL new queued task
110: */
111: sched_task_t *
1.5 misho 112: schedRead(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, int fd,
113: void *opt_data, size_t opt_dlen)
1.1 misho 114: {
115: sched_task_t *task;
116: void *ptr;
117:
118: if (!root || !func)
119: return NULL;
120:
121: /* get new task */
1.4 misho 122: if (!(task = _sched_useTask(root)))
123: return NULL;
1.1 misho 124:
125: memset(task, 0, sizeof(sched_task_t));
126: task->task_id = 0;
1.4 misho 127: task->task_lock = 0;
1.1 misho 128: task->task_func = func;
1.5 misho 129: TASK_TYPE(task) = taskREAD;
130: TASK_ROOT(task) = root;
1.1 misho 131:
132: TASK_ARG(task) = arg;
1.2 misho 133: TASK_FD(task) = fd;
1.1 misho 134:
1.5 misho 135: TASK_DATA(task) = opt_data;
136: TASK_DATLEN(task) = opt_dlen;
137:
1.1 misho 138: if (root->root_hooks.hook_add.read)
139: ptr = root->root_hooks.hook_add.read(task, NULL);
140: else
141: ptr = NULL;
142:
1.5 misho 143: if (!ptr) {
144: #ifdef HAVE_LIBPTHREAD
145: pthread_mutex_lock(&root->root_mtx[taskREAD]);
146: #endif
1.1 misho 147: TAILQ_INSERT_TAIL(&root->root_read, task, task_node);
1.5 misho 148: #ifdef HAVE_LIBPTHREAD
149: pthread_mutex_unlock(&root->root_mtx[taskREAD]);
150: #endif
151: } else
1.4 misho 152: task = _sched_unuseTask(task);
1.1 misho 153:
154: return task;
155: }
156:
157: /*
1.2 misho 158: * schedWrite() - Add WRITE I/O task to scheduler queue
1.6 misho 159: *
1.1 misho 160: * @root = root task
161: * @func = task execution function
162: * @arg = 1st func argument
1.2 misho 163: * @fd = fd handle
1.5 misho 164: * @opt_data = Optional data
165: * @opt_dlen = Optional data length
1.1 misho 166: * return: NULL error or !=NULL new queued task
167: */
168: sched_task_t *
1.5 misho 169: schedWrite(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, int fd,
170: void *opt_data, size_t opt_dlen)
1.1 misho 171: {
172: sched_task_t *task;
173: void *ptr;
174:
175: if (!root || !func)
176: return NULL;
177:
178: /* get new task */
1.4 misho 179: if (!(task = _sched_useTask(root)))
180: return NULL;
1.1 misho 181:
182: memset(task, 0, sizeof(sched_task_t));
183: task->task_id = 0;
1.4 misho 184: task->task_lock = 0;
1.1 misho 185: task->task_func = func;
1.5 misho 186: TASK_TYPE(task) = taskWRITE;
187: TASK_ROOT(task) = root;
1.1 misho 188:
189: TASK_ARG(task) = arg;
1.2 misho 190: TASK_FD(task) = fd;
1.1 misho 191:
1.5 misho 192: TASK_DATA(task) = opt_data;
193: TASK_DATLEN(task) = opt_dlen;
194:
1.1 misho 195: if (root->root_hooks.hook_add.write)
196: ptr = root->root_hooks.hook_add.write(task, NULL);
197: else
198: ptr = NULL;
199:
1.5 misho 200: if (!ptr) {
201: #ifdef HAVE_LIBPTHREAD
202: pthread_mutex_lock(&root->root_mtx[taskWRITE]);
203: #endif
1.1 misho 204: TAILQ_INSERT_TAIL(&root->root_write, task, task_node);
1.5 misho 205: #ifdef HAVE_LIBPTHREAD
206: pthread_mutex_unlock(&root->root_mtx[taskWRITE]);
207: #endif
208: } else
1.4 misho 209: task = _sched_unuseTask(task);
1.1 misho 210:
211: return task;
212: }
213:
214: /*
1.8.2.1 ! misho 215: * schedNode() - Add NODE task to scheduler queue
! 216: *
! 217: * @root = root task
! 218: * @func = task execution function
! 219: * @arg = 1st func argument
! 220: * @fd = fd handle
! 221: * @opt_data = Optional data
! 222: * @opt_dlen = Optional data length
! 223: * return: NULL error or !=NULL new queued task
! 224: */
! 225: sched_task_t *
! 226: schedNode(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, int fd,
! 227: void *opt_data, size_t opt_dlen)
! 228: {
! 229: sched_task_t *task;
! 230: void *ptr;
! 231:
! 232: if (!root || !func)
! 233: return NULL;
! 234:
! 235: /* get new task */
! 236: if (!(task = _sched_useTask(root)))
! 237: return NULL;
! 238:
! 239: memset(task, 0, sizeof(sched_task_t));
! 240: task->task_id = 0;
! 241: task->task_lock = 0;
! 242: task->task_func = func;
! 243: TASK_TYPE(task) = taskNODE;
! 244: TASK_ROOT(task) = root;
! 245:
! 246: TASK_ARG(task) = arg;
! 247: TASK_FD(task) = fd;
! 248:
! 249: TASK_DATA(task) = opt_data;
! 250: TASK_DATLEN(task) = opt_dlen;
! 251:
! 252: if (root->root_hooks.hook_add.node)
! 253: ptr = root->root_hooks.hook_add.node(task, NULL);
! 254: else
! 255: ptr = NULL;
! 256:
! 257: if (!ptr) {
! 258: #ifdef HAVE_LIBPTHREAD
! 259: pthread_mutex_lock(&root->root_mtx[taskNODE]);
! 260: #endif
! 261: TAILQ_INSERT_TAIL(&root->root_node, task, task_node);
! 262: #ifdef HAVE_LIBPTHREAD
! 263: pthread_mutex_unlock(&root->root_mtx[taskNODE]);
! 264: #endif
! 265: } else
! 266: task = _sched_unuseTask(task);
! 267:
! 268: return task;
! 269: }
! 270:
! 271: /*
! 272: * schedProc() - Add PROC task to scheduler queue
! 273: *
! 274: * @root = root task
! 275: * @func = task execution function
! 276: * @arg = 1st func argument
! 277: * @pid = PID
! 278: * @opt_data = Optional data
! 279: * @opt_dlen = Optional data length
! 280: * return: NULL error or !=NULL new queued task
! 281: */
! 282: sched_task_t *
! 283: schedProc(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, u_long pid,
! 284: void *opt_data, size_t opt_dlen)
! 285: {
! 286: sched_task_t *task;
! 287: void *ptr;
! 288:
! 289: if (!root || !func)
! 290: return NULL;
! 291:
! 292: /* get new task */
! 293: if (!(task = _sched_useTask(root)))
! 294: return NULL;
! 295:
! 296: memset(task, 0, sizeof(sched_task_t));
! 297: task->task_id = 0;
! 298: task->task_lock = 0;
! 299: task->task_func = func;
! 300: TASK_TYPE(task) = taskPROC;
! 301: TASK_ROOT(task) = root;
! 302:
! 303: TASK_ARG(task) = arg;
! 304: TASK_VAL(task) = pid;
! 305:
! 306: TASK_DATA(task) = opt_data;
! 307: TASK_DATLEN(task) = opt_dlen;
! 308:
! 309: if (root->root_hooks.hook_add.proc)
! 310: ptr = root->root_hooks.hook_add.proc(task, NULL);
! 311: else
! 312: ptr = NULL;
! 313:
! 314: if (!ptr) {
! 315: #ifdef HAVE_LIBPTHREAD
! 316: pthread_mutex_lock(&root->root_mtx[taskPROC]);
! 317: #endif
! 318: TAILQ_INSERT_TAIL(&root->root_proc, task, task_node);
! 319: #ifdef HAVE_LIBPTHREAD
! 320: pthread_mutex_unlock(&root->root_mtx[taskPROC]);
! 321: #endif
! 322: } else
! 323: task = _sched_unuseTask(task);
! 324:
! 325: return task;
! 326: }
! 327:
! 328: /*
! 329: * schedUser() - Add trigger USER task to scheduler queue
! 330: *
! 331: * @root = root task
! 332: * @func = task execution function
! 333: * @arg = 1st func argument
! 334: * @id = Trigger ID
! 335: * @opt_data = Optional data
! 336: * @opt_dlen = Optional data length
! 337: * return: NULL error or !=NULL new queued task
! 338: */
! 339: sched_task_t *
! 340: schedUser(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, u_long id,
! 341: void *opt_data, size_t opt_dlen)
! 342: {
! 343: sched_task_t *task;
! 344: void *ptr;
! 345:
! 346: if (!root || !func)
! 347: return NULL;
! 348:
! 349: /* get new task */
! 350: if (!(task = _sched_useTask(root)))
! 351: return NULL;
! 352:
! 353: memset(task, 0, sizeof(sched_task_t));
! 354: task->task_id = 0;
! 355: task->task_lock = 0;
! 356: task->task_func = func;
! 357: TASK_TYPE(task) = taskUSER;
! 358: TASK_ROOT(task) = root;
! 359:
! 360: TASK_ARG(task) = arg;
! 361: TASK_VAL(task) = id;
! 362:
! 363: TASK_DATA(task) = opt_data;
! 364: TASK_DATLEN(task) = opt_dlen;
! 365:
! 366: if (root->root_hooks.hook_add.user)
! 367: ptr = root->root_hooks.hook_add.user(task, NULL);
! 368: else
! 369: ptr = NULL;
! 370:
! 371: if (!ptr) {
! 372: #ifdef HAVE_LIBPTHREAD
! 373: pthread_mutex_lock(&root->root_mtx[taskUSER]);
! 374: #endif
! 375: TAILQ_INSERT_TAIL(&root->root_user, task, task_node);
! 376: #ifdef HAVE_LIBPTHREAD
! 377: pthread_mutex_unlock(&root->root_mtx[taskUSER]);
! 378: #endif
! 379: } else
! 380: task = _sched_unuseTask(task);
! 381:
! 382: return task;
! 383: }
! 384:
! 385: /*
! 386: * schedSignal() - Add SIGNAL task to scheduler queue
! 387: *
! 388: * @root = root task
! 389: * @func = task execution function
! 390: * @arg = 1st func argument
! 391: * @sig = Signal
! 392: * @opt_data = Optional data
! 393: * @opt_dlen = Optional data length
! 394: * return: NULL error or !=NULL new queued task
! 395: */
! 396: sched_task_t *
! 397: schedSignal(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, u_long sig,
! 398: void *opt_data, size_t opt_dlen)
! 399: {
! 400: sched_task_t *task;
! 401: void *ptr;
! 402:
! 403: if (!root || !func)
! 404: return NULL;
! 405:
! 406: /* get new task */
! 407: if (!(task = _sched_useTask(root)))
! 408: return NULL;
! 409:
! 410: memset(task, 0, sizeof(sched_task_t));
! 411: task->task_id = 0;
! 412: task->task_lock = 0;
! 413: task->task_func = func;
! 414: TASK_TYPE(task) = taskSIGNAL;
! 415: TASK_ROOT(task) = root;
! 416:
! 417: TASK_ARG(task) = arg;
! 418: TASK_VAL(task) = sig;
! 419:
! 420: TASK_DATA(task) = opt_data;
! 421: TASK_DATLEN(task) = opt_dlen;
! 422:
! 423: if (root->root_hooks.hook_add.signal)
! 424: ptr = root->root_hooks.hook_add.signal(task, NULL);
! 425: else
! 426: ptr = NULL;
! 427:
! 428: if (!ptr) {
! 429: #ifdef HAVE_LIBPTHREAD
! 430: pthread_mutex_lock(&root->root_mtx[taskSIGNAL]);
! 431: #endif
! 432: TAILQ_INSERT_TAIL(&root->root_signal, task, task_node);
! 433: #ifdef HAVE_LIBPTHREAD
! 434: pthread_mutex_unlock(&root->root_mtx[taskSIGNAL]);
! 435: #endif
! 436: } else
! 437: task = _sched_unuseTask(task);
! 438:
! 439: return task;
! 440: }
! 441:
! 442: /*
1.8 misho 443: * schedAlarm() - Add ALARM task to scheduler queue
444: *
445: * @root = root task
446: * @func = task execution function
447: * @arg = 1st func argument
448: * @ts = timeout argument structure, minimum alarm timer resolution is 1msec!
449: * @opt_data = Optional data
450: * @opt_dlen = Optional data length
451: * return: NULL error or !=NULL new queued task
452: */
453: sched_task_t *
454: schedAlarm(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, struct timespec ts,
455: void *opt_data, size_t opt_dlen)
456: {
457: sched_task_t *task;
458: void *ptr;
459:
460: if (!root || !func)
461: return NULL;
462:
463: /* get new task */
464: if (!(task = _sched_useTask(root)))
465: return NULL;
466:
467: memset(task, 0, sizeof(sched_task_t));
468: task->task_id = 0;
469: task->task_lock = 0;
470: task->task_func = func;
471: TASK_TYPE(task) = taskALARM;
472: TASK_ROOT(task) = root;
473:
474: TASK_ARG(task) = arg;
475: TASK_TS(task) = ts;
476:
477: TASK_DATA(task) = opt_data;
478: TASK_DATLEN(task) = opt_dlen;
479:
480: if (root->root_hooks.hook_add.alarm)
481: ptr = root->root_hooks.hook_add.alarm(task, NULL);
482: else
483: ptr = NULL;
484:
485: if (!ptr) {
486: #ifdef HAVE_LIBPTHREAD
487: pthread_mutex_lock(&root->root_mtx[taskALARM]);
488: #endif
489: TAILQ_INSERT_TAIL(&root->root_alarm, task, task_node);
490: #ifdef HAVE_LIBPTHREAD
491: pthread_mutex_unlock(&root->root_mtx[taskALARM]);
492: #endif
493: } else
494: task = _sched_unuseTask(task);
495:
496: return task;
497: }
498:
499: /*
1.1 misho 500: * schedTimer() - Add TIMER task to scheduler queue
1.6 misho 501: *
1.1 misho 502: * @root = root task
503: * @func = task execution function
504: * @arg = 1st func argument
1.5 misho 505: * @ts = timeout argument structure
506: * @opt_data = Optional data
507: * @opt_dlen = Optional data length
1.1 misho 508: * return: NULL error or !=NULL new queued task
509: */
510: sched_task_t *
1.5 misho 511: schedTimer(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, struct timespec ts,
512: void *opt_data, size_t opt_dlen)
1.1 misho 513: {
514: sched_task_t *task, *t = NULL;
515: void *ptr;
1.5 misho 516: struct timespec now;
1.1 misho 517:
518: if (!root || !func)
519: return NULL;
520:
521: /* get new task */
1.4 misho 522: if (!(task = _sched_useTask(root)))
523: return NULL;
1.1 misho 524:
525: memset(task, 0, sizeof(sched_task_t));
526: task->task_id = 0;
1.4 misho 527: task->task_lock = 0;
1.1 misho 528: task->task_func = func;
1.5 misho 529: TASK_TYPE(task) = taskTIMER;
530: TASK_ROOT(task) = root;
1.1 misho 531:
532: TASK_ARG(task) = arg;
533:
1.5 misho 534: TASK_DATA(task) = opt_data;
535: TASK_DATLEN(task) = opt_dlen;
536:
1.1 misho 537: /* calculate timeval structure */
1.5 misho 538: clock_gettime(CLOCK_MONOTONIC, &now);
539: now.tv_sec += ts.tv_sec;
540: now.tv_nsec += ts.tv_nsec;
541: if (now.tv_nsec >= 1000000000L) {
1.1 misho 542: now.tv_sec++;
1.5 misho 543: now.tv_nsec -= 1000000000L;
544: } else if (now.tv_nsec < 0) {
1.1 misho 545: now.tv_sec--;
1.5 misho 546: now.tv_nsec += 1000000000L;
1.1 misho 547: }
1.5 misho 548: TASK_TS(task) = now;
1.1 misho 549:
550: if (root->root_hooks.hook_add.timer)
551: ptr = root->root_hooks.hook_add.timer(task, NULL);
552: else
553: ptr = NULL;
554:
555: if (!ptr) {
1.5 misho 556: #ifdef HAVE_LIBPTHREAD
557: pthread_mutex_lock(&root->root_mtx[taskTIMER]);
558: #endif
1.1 misho 559: #ifdef TIMER_WITHOUT_SORT
560: TAILQ_INSERT_TAIL(&root->root_timer, task, task_node);
561: #else
562: TAILQ_FOREACH(t, &root->root_timer, task_node)
1.5 misho 563: if (sched_timespeccmp(&TASK_TS(task), &TASK_TS(t), -) < 1)
1.1 misho 564: break;
565: if (!t)
566: TAILQ_INSERT_TAIL(&root->root_timer, task, task_node);
567: else
568: TAILQ_INSERT_BEFORE(t, task, task_node);
569: #endif
1.5 misho 570: #ifdef HAVE_LIBPTHREAD
571: pthread_mutex_unlock(&root->root_mtx[taskTIMER]);
572: #endif
1.4 misho 573: } else
574: task = _sched_unuseTask(task);
1.1 misho 575:
576: return task;
577: }
578:
579: /*
580: * schedEvent() - Add EVENT task to scheduler queue
1.6 misho 581: *
1.1 misho 582: * @root = root task
583: * @func = task execution function
584: * @arg = 1st func argument
1.2 misho 585: * @val = additional func argument
1.5 misho 586: * @opt_data = Optional data
587: * @opt_dlen = Optional data length
1.1 misho 588: * return: NULL error or !=NULL new queued task
589: */
590: sched_task_t *
1.5 misho 591: schedEvent(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, u_long val,
592: void *opt_data, size_t opt_dlen)
1.1 misho 593: {
594: sched_task_t *task;
595: void *ptr;
596:
597: if (!root || !func)
598: return NULL;
599:
600: /* get new task */
1.4 misho 601: if (!(task = _sched_useTask(root)))
602: return NULL;
1.1 misho 603:
604: memset(task, 0, sizeof(sched_task_t));
605: task->task_id = 0;
1.4 misho 606: task->task_lock = 0;
1.1 misho 607: task->task_func = func;
1.5 misho 608: TASK_TYPE(task) = taskEVENT;
609: TASK_ROOT(task) = root;
1.1 misho 610:
611: TASK_ARG(task) = arg;
1.2 misho 612: TASK_VAL(task) = val;
1.1 misho 613:
1.5 misho 614: TASK_DATA(task) = opt_data;
615: TASK_DATLEN(task) = opt_dlen;
616:
1.1 misho 617: if (root->root_hooks.hook_add.event)
618: ptr = root->root_hooks.hook_add.event(task, NULL);
619: else
620: ptr = NULL;
621:
1.5 misho 622: if (!ptr) {
623: #ifdef HAVE_LIBPTHREAD
624: pthread_mutex_lock(&root->root_mtx[taskEVENT]);
625: #endif
1.1 misho 626: TAILQ_INSERT_TAIL(&root->root_event, task, task_node);
1.5 misho 627: #ifdef HAVE_LIBPTHREAD
628: pthread_mutex_unlock(&root->root_mtx[taskEVENT]);
629: #endif
630: } else
1.4 misho 631: task = _sched_unuseTask(task);
1.1 misho 632:
633: return task;
634: }
635:
636:
637: /*
638: * schedEventLo() - Add EVENT_Lo task to scheduler queue
1.6 misho 639: *
1.1 misho 640: * @root = root task
641: * @func = task execution function
642: * @arg = 1st func argument
1.2 misho 643: * @val = additional func argument
1.5 misho 644: * @opt_data = Optional data
645: * @opt_dlen = Optional data length
1.1 misho 646: * return: NULL error or !=NULL new queued task
647: */
648: sched_task_t *
1.5 misho 649: schedEventLo(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, u_long val,
650: void *opt_data, size_t opt_dlen)
1.1 misho 651: {
652: sched_task_t *task;
653: void *ptr;
654:
655: if (!root || !func)
656: return NULL;
657:
658: /* get new task */
1.4 misho 659: if (!(task = _sched_useTask(root)))
660: return NULL;
1.1 misho 661:
662: memset(task, 0, sizeof(sched_task_t));
663: task->task_id = 0;
1.4 misho 664: task->task_lock = 0;
1.1 misho 665: task->task_func = func;
1.5 misho 666: TASK_TYPE(task) = taskEVENT;
667: TASK_ROOT(task) = root;
1.1 misho 668:
669: TASK_ARG(task) = arg;
1.2 misho 670: TASK_VAL(task) = val;
1.1 misho 671:
1.5 misho 672: TASK_DATA(task) = opt_data;
673: TASK_DATLEN(task) = opt_dlen;
674:
1.1 misho 675: if (root->root_hooks.hook_add.eventlo)
676: ptr = root->root_hooks.hook_add.eventlo(task, NULL);
677: else
678: ptr = NULL;
679:
1.5 misho 680: if (!ptr) {
681: #ifdef HAVE_LIBPTHREAD
682: pthread_mutex_lock(&root->root_mtx[taskEVENTLO]);
683: #endif
1.1 misho 684: TAILQ_INSERT_TAIL(&root->root_eventlo, task, task_node);
1.5 misho 685: #ifdef HAVE_LIBPTHREAD
686: pthread_mutex_unlock(&root->root_mtx[taskEVENTLO]);
687: #endif
688: } else
1.4 misho 689: task = _sched_unuseTask(task);
1.1 misho 690:
691: return task;
692: }
693:
694: /*
695: * schedCallOnce() - Call once from scheduler
1.6 misho 696: *
1.1 misho 697: * @root = root task
698: * @func = task execution function
699: * @arg = 1st func argument
1.2 misho 700: * @val = additional func argument
1.5 misho 701: * @opt_data = Optional data
702: * @opt_dlen = Optional data length
1.2 misho 703: * return: return value from called func
1.1 misho 704: */
705: sched_task_t *
1.5 misho 706: schedCallOnce(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, u_long val,
707: void *opt_data, size_t opt_dlen)
1.1 misho 708: {
709: sched_task_t *task;
1.2 misho 710: void *ret;
1.1 misho 711:
712: if (!root || !func)
713: return NULL;
714:
715: /* get new task */
1.4 misho 716: if (!(task = _sched_useTask(root)))
717: return NULL;
1.1 misho 718:
719: memset(task, 0, sizeof(sched_task_t));
720: task->task_id = 0;
1.4 misho 721: task->task_lock = 0;
1.1 misho 722: task->task_func = func;
1.5 misho 723: TASK_TYPE(task) = taskEVENT;
724: TASK_ROOT(task) = root;
1.1 misho 725:
726: TASK_ARG(task) = arg;
1.2 misho 727: TASK_VAL(task) = val;
1.1 misho 728:
1.5 misho 729: TASK_DATA(task) = opt_data;
730: TASK_DATLEN(task) = opt_dlen;
731:
1.2 misho 732: ret = schedCall(task);
1.1 misho 733:
1.4 misho 734: _sched_unuseTask(task);
1.2 misho 735: return ret;
1.1 misho 736: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>