diff options
author | Michael I. Bushnell <mib@gnu.org> | 1995-08-09 15:23:50 +0000 |
---|---|---|
committer | Michael I. Bushnell <mib@gnu.org> | 1995-08-09 15:23:50 +0000 |
commit | 050573a5bb4dcbd9818b39171db04b1d8b518b8e (patch) | |
tree | e6bab7fa77052e855485586f4895d5f0e713ebed | |
parent | bab4a550c34c86760becf2b87f34f0dbc1b132c8 (diff) |
Formerly timer-emul.c.~2~
-rw-r--r-- | pfinet/timer-emul.c | 79 |
1 files changed, 56 insertions, 23 deletions
diff --git a/pfinet/timer-emul.c b/pfinet/timer-emul.c index 4b2e0a33..aa23c82a 100644 --- a/pfinet/timer-emul.c +++ b/pfinet/timer-emul.c @@ -18,49 +18,82 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ +#include <linux/timer.h> +#include <asm/system.h> + + static void -timer_function ((any_t) timerp) +timer_function (any_t timerp) { struct timer_list *timer = timerp; - - msleep (timerp->expires); - - begin_interrupt (); - (*timer->function)(timer->data); - end_interrupt (); - timer->thread = 0; + mach_port_t recv; + error_t err; + + recv = mach_reply_port (); + + timer->thread = mach_thread_self (); + + err = mach_msg (NULL, MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT, + 0, 0, recv, timer->expires, MACH_PORT_NULL); + + timer->thread = MACH_PORT_NULL; + + mach_port_destroy (mach_task_self (), recv); + + if (!err) + { + begin_interrupt (); + (*timer->function)(timer->data); + end_interrupt (); + } } void add_timer (struct timer_list *timer) { - cthread_t thread; - - timer->thread = 0; - thread = cthread_fork (timer_function, timer); - timer->thread = thread; - cthread_detach (thread); + timer->thread = -1; + cthread_detach (cthread_fork ((cthread_fn_t) timer_function, timer)); } -void +int del_timer (struct timer_list *timer) { - if (timer->thread) + thread_t thread; + + + if (timer->thread == -1) { - int flags; - - save_flags (flags); - cli (); - cthread_kill (timer->thread); - restore_flags (flags); + /* It hasn't had a chance to set its ID. Wait a bit + until it does. */ + do + swtch_pri (0); + while (timer->thread == -1); } + + thread = timer->thread; + if (thread == MACH_PORT_NULL) + return 0; /* ??? */ + + thread_suspend (thread); + + /* Test again, because it might have run and completed the mach_msg after + we tested above and before we suspended, and we don't want to abort + the mach_port_destroy and certainly not anything inside the timer function\ + which might have started running. */ + if (timer->thread) + thread_abort (thread); + + thread_resume (thread); + + /* What to return? */ + return 0; /* ???*/ } void init_timer (struct timer_list *timer) { - timer->thread = 0; + timer->thread = MACH_PORT_NULL; } |