Annotation of XNU/osfmk/kern/thread_pool.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * @OSF_FREE_COPYRIGHT@
                     24:  */
                     25: /*
                     26:  * HISTORY
                     27:  * 
                     28:  * Revision 1.1.1.1  1998/09/22 21:05:32  wsanchez
                     29:  * Import of Mac OS X kernel (~semeria)
                     30:  *
                     31:  * Revision 1.1.1.1  1998/03/07 02:25:57  wsanchez
                     32:  * Import of OSF Mach kernel (~mburg)
                     33:  *
                     34:  * Revision 1.1.7.6  1995/08/21  20:44:57  devrcs
                     35:  *     Fix ri-osc CR1405: Zero act->thread_pool_next when act not on pool.
                     36:  *     [1995/07/25  20:19:06  bolinger]
                     37:  *
                     38:  * Revision 1.1.7.5  1995/01/18  18:35:00  ezf
                     39:  *     updated Utah CR notice
                     40:  *     [1995/01/18  18:30:33  ezf]
                     41:  * 
                     42:  * Revision 1.1.7.4  1995/01/10  05:15:20  devrcs
                     43:  *     mk6 CR801 - merge up from nmk18b4 to nmk18b7
                     44:  *     Comments from merged code below, as marked
                     45:  *     [1994/12/09  21:10:54  dwm]
                     46:  * 
                     47:  *     mk6 CR668 - 1.3b26 merge
                     48:  *     event_t casts
                     49:  *     [1994/11/04  09:39:15  dwm]
                     50:  * 
                     51:  * Revision 1.1.7.3  1994/11/23  16:01:15  devrcs
                     52:  *     BEGIN comments from merge of nmk18b4 - nmk18b7
                     53:  *     Cleared `handlers' field of activation when returning
                     54:  *     it to thread pool.
                     55:  *     [1994/11/23  03:48:31  burke]
                     56:  * 
                     57:  *     Added an assert to `thread_pool_put_act()' to check
                     58:  *     for presence of handlers when returning an activation
                     59:  *     to its pool.
                     60:  *     [1994/11/18  13:36:29  rkc]
                     61:  * 
                     62:  *     Changed `thread_pool_put_act()'s call to `act_set_thread_pool()' to
                     63:  *     be a call to `act_locked_act_set_thread_pool()' to obey locking
                     64:  *     assumptions.
                     65:  *     [1994/11/10  23:29:51  rkc]
                     66:  * 
                     67:  *     Cosmetic changes to thread_pool_put_act.
                     68:  *     [1994/11/09  21:49:57  watkins]
                     69:  * 
                     70:  *     Check out for merge.
                     71:  *     [1994/11/09  14:16:43  watkins]
                     72:  * 
                     73:  * Revision 1.1.9.2  1994/11/08  15:32:42  watkins
                     74:  *     Add thread_pool_put_act.
                     75:  *     END comments from merge of nmk18b4 - nmk18b7
                     76:  *     [1994/11/09  14:16:33  watkins]
                     77:  * 
                     78:  * Revision 1.1.7.2  1994/09/23  02:31:05  ezf
                     79:  *     change marker to not FREE
                     80:  *     [1994/09/22  21:38:01  ezf]
                     81:  * 
                     82:  * Revision 1.1.7.1  1994/09/02  02:40:54  watkins
                     83:  *     Check for destroyed thread pool port after thread_pool_get_act
                     84:  *     blocks.
                     85:  *     [1994/09/02  02:37:46  watkins]
                     86:  * 
                     87:  * Revision 1.1.2.8  1994/06/09  14:14:04  dswartz
                     88:  *     Preemption merge.
                     89:  *     [1994/06/09  14:08:35  dswartz]
                     90:  * 
                     91:  * Revision 1.1.2.7  1994/06/01  19:30:10  bolinger
                     92:  *     mk6 CR125:  Update to reflect new naming for thread_pool of
                     93:  *     thread_act.
                     94:  *     [1994/06/01  19:14:46  bolinger]
                     95:  * 
                     96:  * Revision 1.1.2.6  1994/03/17  22:38:34  dwm
                     97:  *     The infamous name change:  thread_activation + thread_shuttle = thread.
                     98:  *     [1994/03/17  21:28:15  dwm]
                     99:  * 
                    100:  * Revision 1.1.2.5  1994/02/09  00:42:29  dwm
                    101:  *     Put a variety of debugging code under MACH_ASSERT,
                    102:  *     to enhance PROD performance a bit.
                    103:  *     [1994/02/09  00:35:07  dwm]
                    104:  * 
                    105:  * Revision 1.1.2.4  1994/02/04  03:46:25  condict
                    106:  *     Put if MACH_ASSERT around debugging printfs.
                    107:  *     [1994/02/04  03:44:10  condict]
                    108:  * 
                    109:  * Revision 1.1.2.3  1994/01/21  23:45:15  dwm
                    110:  *     Thread_pools now embedded directly in port/pset.
                    111:  *     Adjust thread_pool_create.
                    112:  *     [1994/01/21  23:43:18  dwm]
                    113:  * 
                    114:  * Revision 1.1.2.2  1994/01/14  18:42:01  bolinger
                    115:  *     Rename thread_pool_block() to thread_pool_get_act() [sic], to
                    116:  *     better reflect its function.  Add leading comment and assertion
                    117:  *     checks.
                    118:  *     [1994/01/14  18:18:11  bolinger]
                    119:  * 
                    120:  * Revision 1.1.2.1  1994/01/12  17:53:17  dwm
                    121:  *     Coloc: initial restructuring to follow Utah model.
                    122:  *     [1994/01/12  17:15:21  dwm]
                    123:  * 
                    124:  * $EndLog$
                    125:  */
                    126: /*
                    127:  * Copyright (c) 1993 The University of Utah and
                    128:  * the Computer Systems Laboratory (CSL).  All rights reserved.
                    129:  *
                    130:  * Permission to use, copy, modify and distribute this software and its
                    131:  * documentation is hereby granted, provided that both the copyright
                    132:  * notice and this permission notice appear in all copies of the
                    133:  * software, derivative works or modified versions, and any portions
                    134:  * thereof, and that both notices appear in supporting documentation.
                    135:  *
                    136:  * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
                    137:  * IS" CONDITION.  THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
                    138:  * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                    139:  *
                    140:  * CSL requests users of this software to return to [email protected] any
                    141:  * improvements that they make and grant CSL redistribution rights.
                    142:  *
                    143:  *      Author: Bryan Ford, University of Utah CSL
                    144:  *
                    145:  *     File:   thread_pool.c
                    146:  *
                    147:  *     thread_pool management routines
                    148:  *
                    149:  */
                    150: 
                    151: #include <kern/ipc_mig.h>
                    152: #include <kern/ipc_tt.h>
                    153: #include <kern/mach_param.h>
                    154: #include <kern/machine.h>
                    155: #include <kern/misc_protos.h>
                    156: #include <kern/processor.h>
                    157: #include <kern/queue.h>
                    158: #include <kern/sched.h>
                    159: #include <kern/sched_prim.h>
                    160: #include <kern/task.h>
                    161: #include <kern/thread_act.h>
                    162: 
                    163: #include <mach/kern_return.h>
                    164: #include <kern/thread_pool.h>
                    165: #include <kern/thread.h>
                    166: #include <kern/zalloc.h>
                    167: #include <kern/misc_protos.h>
                    168: #include <kern/sched_prim.h>
                    169: 
                    170: 
                    171: /* Initialize a new EMPTY thread_pool.  */
                    172: kern_return_t
                    173: thread_pool_init(thread_pool_t new_thread_pool)
                    174: {
                    175:        assert(new_thread_pool != THREAD_POOL_NULL);
                    176: 
                    177:        /* Start with one reference for the caller */
                    178:        new_thread_pool->thr_acts = (struct thread_activation *)0;
                    179:        return KERN_SUCCESS;
                    180: }
                    181: 
                    182: 
                    183: /*
                    184:  * Obtain an activation from a thread pool, blocking if
                    185:  * necessary.  Return the activation locked, since it's
                    186:  * in an inconsistent state (not in a pool, not attached
                    187:  * to a thread).
                    188:  *
                    189:  * Called with ip_lock() held for pool_port.  Returns
                    190:  * the same way.
                    191:  *
                    192:  * If the thread pool port is destroyed while we are blocked,
                    193:  * then return a null activation. Callers must check for this
                    194:  * error case.
                    195:  */
                    196: thread_act_t
                    197: thread_pool_get_act(ipc_port_t pool_port)
                    198: {
                    199:        thread_pool_t thread_pool = &pool_port->ip_thread_pool;
                    200:        thread_act_t thr_act;
                    201: 
                    202: #if    MACH_ASSERT
                    203:        assert(thread_pool != THREAD_POOL_NULL);
                    204:        if (watchacts & WA_ACT_LNK)
                    205:                printf("thread_pool_block: %x, waiting=%d\n",
                    206:                       thread_pool, thread_pool->waiting);
                    207: #endif
                    208: 
                    209:        while ((thr_act = thread_pool->thr_acts) == THR_ACT_NULL) {
                    210:                if (!ip_active(pool_port))
                    211:                        return THR_ACT_NULL;
                    212:                thread_pool->waiting = 1;
                    213:                assert_wait((event_t)thread_pool, THREAD_INTERRUPTIBLE);
                    214:                ip_unlock(pool_port);
                    215:                thread_block((void (*)(void)) 0);       /* block self */
                    216:                ip_lock(pool_port);
                    217:        }
                    218:        assert(thr_act->thread == THREAD_NULL);
                    219:        assert(thr_act->suspend_count == 0);
                    220:        thread_pool->thr_acts = thr_act->thread_pool_next;
                    221:        act_lock(thr_act);
                    222:        thr_act->thread_pool_next = 0;
                    223: 
                    224: #if    MACH_ASSERT
                    225:        if (watchacts & WA_ACT_LNK)
                    226:                printf("thread_pool_block: return %x, next=%x\n",
                    227:                       thr_act, thread_pool->thr_acts);
                    228: #endif
                    229:        return thr_act;
                    230: }
                    231: 
                    232: /*
                    233:  *     thread_pool_put_act
                    234:  *
                    235:  *     Return an activation to its pool. Assumes the activation
                    236:  *     and pool (if it exists) are locked.
                    237:  */
                    238: void
                    239: thread_pool_put_act( thread_act_t thr_act )
                    240: {
                    241:         thread_pool_t   thr_pool;
                    242: 
                    243:        /*
                    244:         *      Find the thread pool for this activation.
                    245:         */     
                    246:         if (thr_act->pool_port)
                    247:             thr_pool = &thr_act->pool_port->ip_thread_pool;
                    248:         else
                    249:             thr_pool = THREAD_POOL_NULL;
                    250: 
                    251:         /* 
                    252:         *      Return act to the thread_pool's list, if it is still
                    253:         *      alive. Otherwise, remove it from its thread_pool, which
                    254:         *      will deallocate it and destroy it.
                    255:         */
                    256:         if (thr_act->active) {
                    257:                 assert(thr_pool);
                    258:                thr_act->handlers = NULL;
                    259:                 thr_act->thread_pool_next = thr_pool->thr_acts;
                    260:                 thr_pool->thr_acts = thr_act;
                    261:                 if (thr_pool->waiting)
                    262:                         thread_pool_wakeup(thr_pool);
                    263:         } else if (thr_pool) {
                    264:                 assert(thr_act->pool_port);
                    265:                 act_locked_act_set_thread_pool(thr_act, IP_NULL);
                    266:         }
                    267: 
                    268:        return;
                    269: }
                    270:  
                    271: 
                    272: /*
                    273:  * Called with ip_lock() held for port containing thread_pool.
                    274:  * Returns same way.
                    275:  */
                    276: void
                    277: thread_pool_wakeup(thread_pool_t thread_pool)
                    278: {
                    279: #if    MACH_ASSERT
                    280:        assert(thread_pool != THREAD_POOL_NULL);
                    281:        if (watchacts & WA_ACT_LNK)
                    282:                printf("thread_pool_wakeup: %x, waiting=%d, head=%x\n",
                    283:                   thread_pool, thread_pool->waiting, thread_pool->thr_acts);
                    284: #endif /* MACH_ASSERT */
                    285: 
                    286:        if (thread_pool->waiting) {
                    287:                thread_wakeup((event_t)thread_pool);
                    288:                thread_pool->waiting = 0;
                    289:        }
                    290: }

unix.superglobalmegacorp.com

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