diff options
Diffstat (limited to 'usr/src/uts/common/os/schedctl.c')
-rw-r--r-- | usr/src/uts/common/os/schedctl.c | 77 |
1 files changed, 60 insertions, 17 deletions
diff --git a/usr/src/uts/common/os/schedctl.c b/usr/src/uts/common/os/schedctl.c index 8a189b3c97..db6ee0e86e 100644 --- a/usr/src/uts/common/os/schedctl.c +++ b/usr/src/uts/common/os/schedctl.c @@ -18,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -55,7 +56,6 @@ #include <vm/as.h> #include <fs/fs_subr.h> - /* * Page handling structures. This is set up as a list of per-page * control structures (sc_page_ctl), with p->p_pagep pointing to @@ -165,12 +165,13 @@ schedctl_lwp_cleanup(kthread_t *t) mutex_exit(&p->p_sc_lock); } + /* * Cleanup the list of schedctl shared pages for the process. * Called from exec() and exit() system calls. */ void -schedctl_proc_cleanup() +schedctl_proc_cleanup(void) { proc_t *p = curproc; sc_page_ctl_t *pagep; @@ -198,6 +199,7 @@ schedctl_proc_cleanup() } } + /* * Called by resume just before switching away from the current thread. * Save new thread state. @@ -248,6 +250,7 @@ schedctl_fork(kthread_t *pt, kthread_t *ct) mutex_exit(&pp->p_sc_lock); } + /* * Returns non-zero if the specified thread shouldn't be preempted at this time. * Called by ts_preempt, ts_tick, and ts_update. @@ -326,16 +329,54 @@ schedctl_finish_sigblock(kthread_t *t) /* + * Return non-zero if the current thread has declared that it has + * a cancellation pending and that cancellation is not disabled. + * If SIGCANCEL is blocked, we must be going over the wire in an + * NFS transaction (sigintr() was called); return zero in this case. + */ +int +schedctl_cancel_pending(void) +{ + sc_shared_t *tdp = curthread->t_schedctl; + + if (tdp != NULL && + (tdp->sc_flgs & SC_CANCEL_FLG) && + !tdp->sc_sigblock && + !sigismember(&curthread->t_hold, SIGCANCEL)) + return (1); + return (0); +} + + +/* + * Inform libc that the kernel returned EINTR from some system call + * due to there being a cancellation pending (SC_CANCEL_FLG set or + * we received an SI_LWP SIGCANCEL while in a system call), rather + * than because of some other signal. User-level code can try to + * recover from receiving other signals, but it can't recover from + * being cancelled. + */ +void +schedctl_cancel_eintr(void) +{ + sc_shared_t *tdp = curthread->t_schedctl; + + if (tdp != NULL) + tdp->sc_flgs |= SC_EINTR_FLG; +} + + +/* * Return non-zero if the current thread has declared that * it is calling into the kernel to park, else return zero. */ int -schedctl_is_park() +schedctl_is_park(void) { sc_shared_t *tdp = curthread->t_schedctl; if (tdp != NULL) - return (tdp->sc_park); + return ((tdp->sc_flgs & SC_PARK_FLG) != 0); /* * If we're here and there is no shared memory (how could * that happen?) then just assume we really are here to park. @@ -343,39 +384,40 @@ schedctl_is_park() return (1); } + /* * Declare thread is parking. * - * libc will set "sc_park = 1" before calling lwpsys_park(0, tid) in order - * to declare that the thread is calling into the kernel to park. + * libc will set "sc_flgs |= SC_PARK_FLG" before calling lwpsys_park(0, tid) + * in order to declare that the thread is calling into the kernel to park. * * This interface exists ONLY to support older versions of libthread which - * are not aware of the sc_park flag. + * are not aware of the SC_PARK_FLG flag. * - * Older versions of libthread which are not aware of the sc_park flag need to - * be modified or emulated to call lwpsys_park(4, ...) instead of + * Older versions of libthread which are not aware of the SC_PARK_FLG flag + * need to be modified or emulated to call lwpsys_park(4, ...) instead of * lwpsys_park(0, ...). This will invoke schedctl_set_park() before * lwp_park() to declare that the thread is parking. */ void -schedctl_set_park() +schedctl_set_park(void) { sc_shared_t *tdp = curthread->t_schedctl; - if (tdp != NULL) - tdp->sc_park = 1; + tdp->sc_flgs |= SC_PARK_FLG; } + /* - * Clear the shared sc_park flag on return from parking in the kernel. + * Clear the parking flag on return from parking in the kernel. */ void -schedctl_unpark() +schedctl_unpark(void) { sc_shared_t *tdp = curthread->t_schedctl; if (tdp != NULL) - tdp->sc_park = 0; + tdp->sc_flgs &= ~SC_PARK_FLG; } @@ -384,7 +426,7 @@ schedctl_unpark() */ void -schedctl_init() +schedctl_init(void) { /* * Amount of page that can hold sc_shared_t structures. If @@ -400,6 +442,7 @@ schedctl_init() sc_bitmap_words = howmany(sc_bitmap_len, BT_NBIPUL); } + int schedctl_shared_alloc(sc_shared_t **kaddrp, uintptr_t *uaddrp) { |