Annotation of Gnu-Mach/kern/thread_swap.c, revision 1.1.1.4

1.1       root        1: /*
                      2:  * Mach Operating System
                      3:  * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
                      4:  * All Rights Reserved.
                      5:  * 
                      6:  * Permission to use, copy, modify and distribute this software and its
                      7:  * documentation is hereby granted, provided that both the copyright
                      8:  * notice and this permission notice appear in all copies of the
                      9:  * software, derivative works or modified versions, and any portions
                     10:  * thereof, and that both notices appear in supporting documentation.
                     11:  * 
                     12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     15:  * 
                     16:  * Carnegie Mellon requests users of this software to return to
                     17:  * 
                     18:  *  Software Distribution Coordinator  or  [email protected]
                     19:  *  School of Computer Science
                     20:  *  Carnegie Mellon University
                     21:  *  Pittsburgh PA 15213-3890
                     22:  * 
                     23:  * any improvements or extensions that they make and grant Carnegie Mellon
                     24:  * the rights to redistribute these changes.
                     25:  */
                     26: /*
                     27:  *
                     28:  *     File:   kern/thread_swap.c
                     29:  *     Author: Avadis Tevanian, Jr.
                     30:  *     Date:   1987
                     31:  *
                     32:  *     Mach thread swapper:
                     33:  *             Find idle threads to swap, freeing up kernel stack resources
                     34:  *             at the expense of allowing them to execute.
                     35:  *
                     36:  *             Swap in threads that need to be run.  This is done here
                     37:  *             by the swapper thread since it cannot be done (in general)
                     38:  *             when the kernel tries to place a thread on a run queue.
                     39:  *
                     40:  *     Note: The act of swapping a thread in Mach does not mean that
                     41:  *     its memory gets forcibly swapped to secondary storage.  The memory
                     42:  *     for the task corresponding to a swapped thread is paged out
                     43:  *     through the normal paging mechanism.
                     44:  *
                     45:  */
                     46: 
                     47: #include <ipc/ipc_kmsg.h>
                     48: #include <kern/counters.h>
1.1.1.2   root       49: #include <kern/debug.h>
1.1       root       50: #include <kern/thread.h>
                     51: #include <kern/lock.h>
                     52: #include <vm/vm_map.h>
                     53: #include <vm/vm_kern.h>
                     54: #include <mach/vm_param.h>
                     55: #include <kern/sched_prim.h>
                     56: #include <kern/processor.h>
                     57: #include <kern/thread_swap.h>
                     58: #include <machine/machspl.h>           /* for splsched */
                     59: 
                     60: 
                     61: 
                     62: queue_head_t           swapin_queue;
                     63: decl_simple_lock_data(,        swapper_lock_data)
                     64: 
                     65: #define swapper_lock()         simple_lock(&swapper_lock_data)
                     66: #define swapper_unlock()       simple_unlock(&swapper_lock_data)
                     67: 
                     68: /*
                     69:  *     swapper_init: [exported]
                     70:  *
                     71:  *     Initialize the swapper module.
                     72:  */
1.1.1.2   root       73: void swapper_init(void)
1.1       root       74: {
                     75:        queue_init(&swapin_queue);
                     76:        simple_lock_init(&swapper_lock_data);
                     77: }
                     78: 
                     79: /*
                     80:  *     thread_swapin: [exported]
                     81:  *
                     82:  *     Place the specified thread in the list of threads to swapin.  It
                     83:  *     is assumed that the thread is locked, therefore we are at splsched.
                     84:  *
                     85:  *     We don't bother with stack_alloc_try to optimize swapin;
                     86:  *     our callers have already tried that route.
                     87:  */
                     88: 
1.1.1.3   root       89: void thread_swapin(thread_t thread)
1.1       root       90: {
                     91:        switch (thread->state & TH_SWAP_STATE) {
                     92:            case TH_SWAPPED:
                     93:                /*
                     94:                 *      Swapped out - queue for swapin thread.
                     95:                 */
                     96:                thread->state = (thread->state & ~TH_SWAP_STATE)
                     97:                                | TH_SW_COMING_IN;
                     98:                swapper_lock();
1.1.1.3   root       99:                enqueue_tail(&swapin_queue, &(thread->links));
1.1       root      100:                swapper_unlock();
                    101:                thread_wakeup((event_t) &swapin_queue);
                    102:                break;
                    103: 
                    104:            case TH_SW_COMING_IN:
                    105:                /*
                    106:                 *      Already queued for swapin thread, or being
                    107:                 *      swapped in.
                    108:                 */
                    109:                break;
                    110: 
                    111:            default:
                    112:                /*
                    113:                 *      Already swapped in.
                    114:                 */
                    115:                panic("thread_swapin");
                    116:        }
                    117: }
                    118: 
                    119: /*
                    120:  *     thread_doswapin:
                    121:  *
                    122:  *     Swapin the specified thread, if it should be runnable, then put
                    123:  *     it on a run queue.  No locks should be held on entry, as it is
                    124:  *     likely that this routine will sleep (waiting for stack allocation).
                    125:  */
1.1.1.4 ! root      126: kern_return_t thread_doswapin(thread_t thread)
1.1       root      127: {
1.1.1.4 ! root      128:        kern_return_t kr;
1.1       root      129:        spl_t   s;
                    130: 
                    131:        /*
                    132:         *      Allocate the kernel stack.
                    133:         */
                    134: 
1.1.1.4 ! root      135:        kr = stack_alloc(thread, thread_continue);
        !           136:        if (kr != KERN_SUCCESS)
        !           137:                return kr;
1.1       root      138: 
                    139:        /*
                    140:         *      Place on run queue.  
                    141:         */
                    142: 
                    143:        s = splsched();
                    144:        thread_lock(thread);
                    145:        thread->state &= ~(TH_SWAPPED | TH_SW_COMING_IN);
                    146:        if (thread->state & TH_RUN)
                    147:                thread_setrun(thread, TRUE);
                    148:        thread_unlock(thread);
                    149:        (void) splx(s);
1.1.1.4 ! root      150:        return KERN_SUCCESS;
1.1       root      151: }
                    152: 
                    153: /*
                    154:  *     swapin_thread: [exported]
                    155:  *
                    156:  *     This procedure executes as a kernel thread.  Threads that need to
                    157:  *     be swapped in are swapped in by this thread.
                    158:  */
1.1.1.3   root      159: void __attribute__((noreturn)) swapin_thread_continue(void)
1.1       root      160: {
                    161:        for (;;) {
1.1.1.3   root      162:                thread_t thread;
1.1       root      163:                spl_t s;
                    164: 
                    165:                s = splsched();
                    166:                swapper_lock();
                    167: 
                    168:                while ((thread = (thread_t) dequeue_head(&swapin_queue))
                    169:                                                        != THREAD_NULL) {
1.1.1.4 ! root      170:                        kern_return_t kr;
1.1       root      171:                        swapper_unlock();
                    172:                        (void) splx(s);
                    173: 
1.1.1.4 ! root      174:                        kr = thread_doswapin(thread);           /* may block */
1.1       root      175: 
                    176:                        s = splsched();
                    177:                        swapper_lock();
1.1.1.4 ! root      178: 
        !           179:                        if (kr != KERN_SUCCESS) {
        !           180:                                enqueue_head(&swapin_queue,
        !           181:                                             (queue_entry_t) thread);
        !           182:                                break;
        !           183:                        }
1.1       root      184:                }
                    185: 
                    186:                assert_wait((event_t) &swapin_queue, FALSE);
                    187:                swapper_unlock();
                    188:                (void) splx(s);
                    189:                counter(c_swapin_thread_block++);
                    190:                thread_block(swapin_thread_continue);
                    191:        }
                    192: }
                    193: 
1.1.1.2   root      194: void swapin_thread(void)
1.1       root      195: {
                    196:        stack_privilege(current_thread());
                    197: 
                    198:        swapin_thread_continue();
                    199:        /*NOTREACHED*/
                    200: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.