Annotation of driverkit/libDriver/Kernel/NXConditionLock.m, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: /*     Copyright (c) 1991 NeXT Computer, Inc.  All rights reserved. 
                     25:  *
                     26:  * NXConditionLock.m. Lock object with exported condition variable, 
                     27:  *     kernel version.
                     28:  *
                     29:  * HISTORY
                     30:  * 01-Aug-91    Doug Mitchell at NeXT
                     31:  *      Created. 
                     32:  */
                     33: 
                     34: #define KERNEL         1
                     35: #define KERNEL_PRIVATE 1
                     36: #define ARCH_PRIVATE   1 
                     37: #undef MACH_USER_API
                     38: 
                     39: #import <machkit/NXLock.h>
                     40: #import <kern/sched_prim.h>
                     41: #import <kernserv/lock.h>
                     42: 
                     43: /*
                     44:  * _priv instance variable points to one of these.
                     45:  */
                     46: struct _priv {
                     47:     simple_lock_t      spin_lock;
                     48:     lock_t             sleep_lock;
                     49:     int                        conditionVar;
                     50: };
                     51: 
                     52: @implementation NXConditionLock
                     53: 
                     54: - init
                     55: {
                     56:     return [self initWith:0];
                     57: }
                     58: 
                     59: - initWith : (int)condition
                     60: {
                     61:        struct _priv    *p = _priv;
                     62:        
                     63:        [super init];
                     64:        
                     65:        if (p == 0) {
                     66:            p = (struct _priv *)kalloc(sizeof (struct _priv));
                     67:            p->spin_lock = simple_lock_alloc();
                     68:            p->sleep_lock = lock_alloc();
                     69: 
                     70:            _priv = p;
                     71:        }
                     72: 
                     73:        simple_lock_init(p->spin_lock);
                     74:        lock_init(p->sleep_lock, TRUE);
                     75:        p->conditionVar = condition;
                     76: 
                     77:        return self;
                     78: }
                     79: 
                     80: - (int) condition
                     81: {
                     82:        struct _priv    *p = _priv;
                     83: 
                     84:        return (p->conditionVar);
                     85: }
                     86: 
                     87: - free
                     88: {
                     89:        struct _priv    *p = _priv;
                     90: 
                     91:        if (p) {
                     92:            lock_free(p->sleep_lock);
                     93:            simple_lock_free(p->spin_lock);
                     94:            kfree(p, sizeof (struct _priv));
                     95:        }
                     96: 
                     97:        return [super free];
                     98: }
                     99: 
                    100: - lock 
                    101: {
                    102:        struct _priv    *p = _priv;
                    103: 
                    104:        lock_write(p->sleep_lock);
                    105: 
                    106:        return self;
                    107: }
                    108: 
                    109: - unlock
                    110: {
                    111:        struct _priv    *p = _priv;
                    112: 
                    113:        thread_wakeup_one(&p->conditionVar);
                    114:        lock_done(p->sleep_lock);
                    115: 
                    116:        return self;
                    117: }
                    118: 
                    119: - lockWhen : (int)condition
                    120: {
                    121:        struct _priv    *p = _priv;
                    122:                
                    123:        /*
                    124:         * First acquire ownership of the entire object.
                    125:         */
                    126:        lock_write(p->sleep_lock); 
                    127:        while (condition != p->conditionVar) {
                    128:        
                    129:                /*
                    130:                 * Need to hold a simple_lock when we call thread_sleep().
                    131:                 * Both _spin_lock and sleep_lock must be held to 
                    132:                 * change _conditionVar.
                    133:                 */
                    134:                simple_lock(p->spin_lock);
                    135:                lock_done(p->sleep_lock);
                    136:                
                    137:                /*
                    138:                 * this is the critical section on a multi in which
                    139:                 * another thread could hold _sleep_lock, but they 
                    140:                 * can't change _conditionVar. Holding _spin_lock here
                    141:                 * (until after assert_wait() is called from 
                    142:                 * thread_sleep()) ensures that we'll be notified
                    143:                 * of changes in _conditionVar.
                    144:                 */
                    145:                thread_sleep((void *)&p->conditionVar, p->spin_lock, FALSE); 
                    146:                lock_write(p->sleep_lock);
                    147:        }
                    148: 
                    149:        return self;
                    150: }
                    151: 
                    152: - unlockWith : (int)condition
                    153: {
                    154:        struct _priv    *p = _priv;
                    155: 
                    156:        /*
                    157:         * _sleep_lock held, but not _spin_lock.
                    158:         */
                    159:        simple_lock(p->spin_lock);
                    160:        p->conditionVar = condition;
                    161:        simple_unlock(p->spin_lock);
                    162:        thread_wakeup_one(&p->conditionVar);
                    163:        lock_done(p->sleep_lock);
                    164: 
                    165:        return self;
                    166: }
                    167: 
                    168: @end

unix.superglobalmegacorp.com

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