|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.