X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=sched.h;h=35e2503e383be3611fc302f5a732e45cf322d506;hp=35b5c636d3d6670810cb1c58f9d6a21408d054a8;hb=HEAD;hpb=50087dc3759d54b7b9e5583d1e5a7544261fe364 diff --git a/sched.h b/sched.h index 35b5c636..ede5e67e 100644 --- a/sched.h +++ b/sched.h @@ -1,8 +1,4 @@ -/* - * Copyright (C) 2006-2009 Andre Noll - * - * Licensed under the GPL v2. For licencing details see COPYING. - */ +/* Copyright (C) 2006 Andre Noll , see file COPYING. */ /** \file sched.h Sched and task structures and exported symbols from sched.c. */ @@ -10,72 +6,96 @@ /** * Paraslash's scheduler. * - * Designed with KISS in mind. It manages two lists of tasks. The pre_select - * list contains pointers to functions that are called before calling select() - * from the main loop. Similarly, \a post_select_list is a list of function - * pointers each of which is called after the select call. Tasks add hooks to - * these lists by registering themselves to the scheduler. + * Designed with KISS in mind. It maintains a list of task structures which is + * extended when a new task is registered. Each task may define a pre_monitor + * function which is called from the scheduler main loop before it calls + * poll(2). Similarly, each task must define a post_monitor function which is + * called after poll(2) returns. + * + * \sa select(2), poll(2). */ struct sched { - /** Initial value before any pre_select call. */ - struct timeval default_timeout; - /** The current timeout for the upcoming select call. */ - struct timeval timeout; - /** fds that should be watched for readability. */ - fd_set rfds; - /** fds that should be watched for writability. */ - fd_set wfds; - /** Highest numbered file descriptor in any of the above fd sets. */ - int max_fileno; - /** In non-NULL, use this function instead of para_select. */ - int (*select_function)(int, fd_set *, fd_set *, struct timeval *); + /** Initial value (in milliseconds) before any pre_monitor call. */ + int default_timeout; + /** The timeout (also in milliseconds) for the next iteration. */ + int timeout; + /** Passed to poll(2). */ + struct pollfd *pfd; + /** Number of elements in the above array, passed to poll(2). */ + unsigned pfd_array_len; + /** Number of fds registered for montitoring so far. */ + unsigned num_pfds; + /** Maps fds to indices of the pfd array. */ + unsigned *pidx; + /** Mumber of elements in the above pidx array. */ + unsigned pidx_array_len; + /** If non-NULL, use this function instead of \ref xpoll(). */ + int (*poll_function)(struct pollfd *fds, nfds_t nfds, int timeout); + /** Tasks which have been registered to the scheduler. */ + struct list_head task_list; }; -/** - * Paraslash's task structure. - * - * Before registering a task to the scheduler, the task structure must be - * filled in properly by the caller. - * - * If one of these functions sets \a t->error to a negative value, the - * task gets unregistered automatically. - * - * \sa struct sched. - */ -struct task { +struct task; + +/** Information that must be supplied by callers of \ref task_register(). */ +struct task_info { + /** Used for log messages and by \ref get_task_list(). */ + const char *name; /** - * The pre select hook of \a t. + * Configure watch fds and impose an upper bound on the I/O timeout. + * + * If this is not NULL, the function is called at each iteration of the + * scheduler's main loop. Its purpose is to tell the scheduler that + * certain file descriptors should be monitored for readiness for I/O. + * The function may also lower the scheduler's timeout value (but shall + * never increase it) to impose an upper bound on the waiting time in + * case no file descriptors happen to be ready. * - * Its purpose is to add file descriptors to the fd sets of the - * scheduler and to decrease the select timeout if necessary. + * \sa \ref time.c. */ - void (*pre_select)(struct sched *s, struct task *t); + void (*pre_monitor)(struct sched *s, void *context); /** - * The postselect hook of \a t. + * Perform I/O on file descriptors which are ready for I/O. * - * Evaluate and act upon the results of the previous select call. + * This mandatory hook is called after the system call which monitors + * file descriptors returns. The function should perform non-blocking + * I/O on those file descriptors which are reported as being ready. + * + * If this function returns a negative value, the scheduler unregisters + * the task. + */ + int (*post_monitor)(struct sched *s, void *context); + /** + * This pointer is saved when the task is registered. It is passed to + * ->pre_monitor() and ->post_monitor(). Usually this is a pointer to the + * struct owned by the caller which contains the task pointer. */ - void (*post_select)(struct sched *s, struct task *t); - /** Whether this task is in error state. */ - int error; - /** Position of the task in the pre_select list of the scheduler. */ - struct list_head pre_select_node; - /** Position of the task in the post_select list of the scheduler. */ - struct list_head post_select_node; - /** Descriptive text and current status of the task. */ - char status[255]; + void *context; }; /** * This is set by the scheduler at the beginning of its main loop. It may be * used (read-only) from everywhere. As none of the functions called by the * scheduler are allowed to block, this value should be accurate enough so that - * there is no need to call gettimeofday() directly. + * there is no need to call clock_gettime() directly. */ -extern struct timeval *now; +extern const struct timeval *now; -void register_task(struct task *t); +struct task *task_register(struct task_info *info, struct sched *s); int schedule(struct sched *s); -char *get_task_list(void); -int kill_task(char *id); -void sched_shutdown(void); +void sched_shutdown(struct sched *s); +char *get_task_list(struct sched *s); +void task_notify(struct task *t, int err); +void task_notify_all(struct sched *s, int err); +int task_get_notification(const struct task *t); +int task_status(const struct task *t); +int task_reap(struct task **tptr); +void sched_min_delay(struct sched *s); +void sched_request_timeout(struct timeval *to, struct sched *s); +void sched_request_timeout_ms(long unsigned ms, struct sched *s); +int sched_request_barrier(struct timeval *barrier, struct sched *s); +int sched_request_barrier_or_min_delay(struct timeval *barrier, struct sched *s); +void sched_monitor_readfd(int fd, struct sched *s); +void sched_monitor_writefd(int fd, struct sched *s); +bool sched_read_ok(int fd, const struct sched *s); +bool sched_write_ok(int fd, const struct sched *s);