Annotation of driverkit/libDriver/Kernel/NXConditionLock.m, revision 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.