Annotation of driverkit/tests/NXLockTest.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: /*
                     25:  * Test of NXLock, NXConditionLock, and NXSpinLock (kernel version).
                     26:  */
                     27:  
                     28: /*
                     29:  * Operations (performed sequentially per msg_id passed to server)
                     30:  */
                     31: #define NXL_LIB_INIT   1               // call IOInitGeneralFuncs()
                     32: #define NXL_OBJ_ALLOC  2               // alloc an Object
                     33: #define NXL_OBJ_INIT   3               // init an Object
                     34: #define NXL_LOCK_INIT  5               // alloc and init all 3 locks
                     35: #define NXL_THREAD     6               // start up ioThread
                     36: #define NXL_PART1      7               // part 1 - NXSpinLock test
                     37: #define NXL_PART2      8               // part 2 - NXLock test
                     38: #define NXL_PART3      9               // part 2 - NXConditionLock test
                     39: 
                     40: /*
                     41:  * Kernel can't do spin lock tests on a single CPU.
                     42:  */
                     43: #define DO_SPINLOCK    0
                     44: 
                     45: #define KERNEL         1
                     46: #define KERNEL_PRIVATE 1               // pick up kernel private files
                     47: 
                     48: #import <machkit/NXLock.h>
                     49: #import <driverkit/generalFuncs.h>
                     50: #import <kernserv/kern_server_types.h>
                     51: #import <mach/message.h>
                     52: 
                     53: static int do_NXLockTest(int opcode);
                     54: static int ioThread(void *param);
                     55: 
                     56: kern_server_t NXLock_ks_var;
                     57: id nxLock;
                     58: id nxCondLock;
                     59: id nxSpinLock;
                     60: int libInitFlag = 1;
                     61: 
                     62: /*
                     63:  * flags mean "I'm waiting for you" when true.
                     64:  */
                     65: boolean_t threadFlag;
                     66: boolean_t mainFlag;
                     67: 
                     68: /*
                     69:  * kernserv callout functions.
                     70:  */
                     71: void locktest_announce(int unit);
                     72: void locktest_port_gone(port_name_t port);
                     73: void locktest_terminate(int unit);
                     74: void locktest_server(msg_header_t *in_p, int unit);
                     75: 
                     76: /* 
                     77:  * we're just placed into memory here.
                     78:  */
                     79: void locktest_announce(int unit) 
                     80: {
                     81:        IOLog("NXLockTest Loaded\n", unit);
                     82: } 
                     83: 
                     84: void locktest_port_gone(port_name_t port) 
                     85: {
                     86:        IOLog("NXLockTest port death\n");
                     87:        
                     88: }
                     89: 
                     90: void locktest_terminate(int unit) 
                     91: {
                     92:        IOLog("NXLockTest Unloaded\n");
                     93: }
                     94: 
                     95: /*
                     96:  * This is invoked upon receipt of any message. (Use the smsg utility to
                     97:  * send an empty message here.)
                     98:  */
                     99: void locktest_server(msg_header_t *in_p, int unit)
                    100: {
                    101:        int opcode = in_p->msg_id;
                    102:        id foo;
                    103:        
                    104:        IOLog("NXLockTest: Starting\n");
                    105:        
                    106: #ifdef TEST_IN_KERNEL
                    107:        doNXLockTest(opcode);
                    108:        goto done;
                    109: #endif TEST_IN_KERNEL
                    110: 
                    111:        /*
                    112:         * First initialize the libraries we'll use. There's no shutdown
                    113:         * needed later (or is there...?).
                    114:         */
                    115:        if(opcode < NXL_LIB_INIT) 
                    116:                goto done;
                    117:        if(!libInitFlag) {
                    118:                IOInitGeneralFuncs();   
                    119:                libInitFlag = 1;
                    120:        }
                    121:        IOLog("IOInitGeneralFunc called\n");
                    122: 
                    123:        /*
                    124:         * Just to try out objc run time, alloc and init an Object.
                    125:         */
                    126:        if(opcode < NXL_OBJ_ALLOC)
                    127:                goto done;
                    128:        foo = [Object alloc];
                    129:        if(opcode < NXL_OBJ_INIT)
                    130:                goto done;
                    131:        IOLog("Object alloc'd\n");
                    132:        [foo init];
                    133:        IOLog("Object init'd\n");
                    134: 
                    135:        do_NXLockTest(opcode);
                    136: 
                    137:        /*
                    138:         * return message to loader.
                    139:         */
                    140: done:
                    141:        msg_send(in_p, 
                    142:                MSG_OPTION_NONE,
                    143:                0);     
                    144: } /* locktest_server() */
                    145: 
                    146: /*
                    147:  * Call to avoid spinning.
                    148:  */
                    149: static void yield()
                    150: {
                    151:        IOSleep(10);
                    152: }
                    153: 
                    154: /*
                    155:  * Actual NXLock test. do_NXLockTest runs from our msg_receive thread in
                    156:  * kernserv. This thread forks off ioThread() and the two perform the
                    157:  * following:
                    158:  *
                    159:  *  part       main                    ioThread
                    160:  *   1         mainFlag FALSE          threadFlag FALSE 
                    161:  *             grab spin lock          wait for mainFlag
                    162:  *             mainFlag TRUE           
                    163:  *             wait for threadFlag
                    164:  *                                     threadFlag TRUE
                    165:  *                                     try to acquire spinLock (held by main)
                    166:  *             mainFlag FALSE
                    167:  *             sleep
                    168:  *             unlock spin lock        
                    169:  *             wait for threadFlag FALSE
                    170:  *                                     unlock spinLock
                    171:  *                                     threadFlag FALSE
                    172:  *
                    173:  *  2          grab nxLock             wait for mainFlag
                    174:  *             mainFlag TRUE           
                    175:  *             wait for threadFlag
                    176:  *                                     threadFlag TRUE
                    177:  *                                     try to acquire nxLock (held by main)
                    178:  *             mainFlag FALSE
                    179:  *             sleep
                    180:  *             unlock nxLock   
                    181:  *             wait for threadFlag FALSE
                    182:  *                                     unlock spinLock
                    183:  *                                     threadFlag FALSE
                    184:  *
                    185:  *  3          grab nxCondLock         wait for mainFlag
                    186:  *             mainFlag TRUE
                    187:  *             wait for threadFlag
                    188:  *                                     threadFlag TRUE
                    189:  *                                     [condLock lockWhen 1]
                    190:  *             mainFlag FALSE
                    191:  *             sleep
                    192:  *             [condLock unlockWith 1]
                    193:  *             [condLock lockWhen 2]
                    194:  *                                     sleep
                    195:  *                                     [condLock unlockWith 2]
                    196:  *             done                    done
                    197:  */
                    198:  
                    199: static int do_NXLockTest(int opcode)
                    200: {
                    201:        if(opcode < NXL_LOCK_INIT)
                    202:                return 0;
                    203:                
                    204:        /*
                    205:         * Init the three locks.
                    206:         */
                    207:        nxLock     = [NXLock new];
                    208:        IOLog("NXLock new'd\n");
                    209:        nxCondLock = [NXConditionLock alloc];
                    210:        [nxCondLock initWith:0];
                    211:        IOLog("NXCondLock initWith:'d\n");
                    212:        nxSpinLock = [NXSpinLock new];
                    213:        IOLog("NXSpinLock new'd\n");
                    214:        
                    215:        if(opcode < NXL_THREAD)
                    216:                return 0;
                    217:                
                    218:        /*
                    219:         * Start up the I/O thread.
                    220:         */
                    221:        IOForkThread((IOThreadFunc)ioThread, (void *)opcode);
                    222:        IOLog("ioThread forked\n");
                    223:        if(opcode < NXL_PART1)
                    224:                return 0;
                    225:                
                    226:        /*
                    227:         * Part 1.
                    228:         */
                    229: #if    DO_SPINLOCK
                    230:        [nxSpinLock lock];
                    231:        mainFlag = TRUE;
                    232:        while(!threadFlag) {
                    233:                yield();
                    234:        }
                    235: 
                    236:        mainFlag = FALSE;
                    237:        IOLog("1 (main) - threadFlag true, main() holds spin lock\n");
                    238:        IOSleep(1);
                    239:        [nxSpinLock unlock];
                    240:        
                    241:        /*
                    242:         * Wait for I/O Thread to finish part 1.
                    243:         */
                    244:        while(threadFlag) {
                    245:                yield();
                    246:        }
                    247: #endif DO_SPINLOCK
                    248: 
                    249:        if(opcode < NXL_PART2)
                    250:                return 0;
                    251:                
                    252:        /*
                    253:         * Part 2.
                    254:         */
                    255:        [nxLock lock];
                    256:        mainFlag = TRUE;
                    257:        while(!threadFlag) {
                    258:                yield();
                    259:        }
                    260:        mainFlag = FALSE;
                    261:        IOLog("2 (main) - threadFlag true, main() holds nxLock\n");
                    262:        IOSleep(1);
                    263:        [nxLock unlock];
                    264:        
                    265:        /*
                    266:         * Wait for I/O Thread to finish part 2.
                    267:         */
                    268:        while(threadFlag) {
                    269:                yield();
                    270:        }
                    271: 
                    272:        if(opcode < NXL_PART3)
                    273:                return 0;
                    274:                
                    275:        /*
                    276:         * Part 3.
                    277:         */             
                    278:        [nxCondLock lock];
                    279:        mainFlag = TRUE;
                    280:        while(!threadFlag) {
                    281:                yield();
                    282:        }
                    283:        IOLog("3 (main) - threadFlag true, main() holds condLock\n");
                    284:        IOSleep(1);
                    285:        [nxCondLock unlockWith:1];
                    286:        [nxCondLock lockWhen:2];
                    287:        IOLog("3 (main) - got condLock:2; done\n");
                    288:        
                    289:        /*
                    290:         * Free the locks.
                    291:         */
                    292:        [nxLock free];
                    293:        [nxCondLock free];
                    294:        [nxSpinLock free];
                    295:        return(0);
                    296: }
                    297: 
                    298: static int ioThread(void *param)
                    299: {
                    300:        int opcode = (int)param;
                    301:        
                    302:        if(opcode < NXL_PART1)
                    303:                goto done;
                    304:                
                    305:        /*
                    306:         * part 1.
                    307:         */
                    308: #if    DO_SPINLOCK
                    309:        while(!mainFlag)
                    310:                ;
                    311:        threadFlag = TRUE;
                    312:        [nxSpinLock lock];
                    313:        IOLog("1 (thread) - thread got spinLock\n");
                    314:        [nxSpinLock unlock];
                    315:        threadFlag = FALSE;
                    316: #endif DO_SPINLOCK
                    317:        
                    318:        if(opcode < NXL_PART2)
                    319:                goto done;
                    320:                
                    321:        /*
                    322:         * part 2.
                    323:         */
                    324:        while(!mainFlag) {
                    325:                yield();
                    326:        }
                    327:        threadFlag = TRUE;
                    328:        [nxLock lock];
                    329:        IOLog("2 (thread) - thread got nxLock\n");
                    330:        [nxLock unlock];
                    331:        threadFlag = FALSE;
                    332:        
                    333:        if(opcode < NXL_PART3)
                    334:                goto done;
                    335: 
                    336:        /*
                    337:         * Part 3.
                    338:         */
                    339:        while(!mainFlag) {
                    340:                yield();
                    341:        }
                    342:        threadFlag = TRUE;
                    343:        [nxCondLock lockWhen:1];
                    344:        IOLog("3 (thread) - got condLock:1\n");
                    345:        IOSleep(1);
                    346:        [nxCondLock unlockWith:2];
                    347:        
                    348:        /*
                    349:         * Done, kill this thread.
                    350:         */
                    351: done:
                    352:        IOExitThread();
                    353: }

unix.superglobalmegacorp.com

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