|
|
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: /* ! 26: * Mach Operating System ! 27: * Copyright (c) 1993-1987 Carnegie Mellon University ! 28: * All Rights Reserved. ! 29: * ! 30: * Permission to use, copy, modify and distribute this software and its ! 31: * documentation is hereby granted, provided that both the copyright ! 32: * notice and this permission notice appear in all copies of the ! 33: * software, derivative works or modified versions, and any portions ! 34: * thereof, and that both notices appear in supporting documentation. ! 35: * ! 36: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 37: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 38: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 39: * ! 40: * Carnegie Mellon requests users of this software to return to ! 41: * ! 42: * Software Distribution Coordinator or [email protected] ! 43: * School of Computer Science ! 44: * Carnegie Mellon University ! 45: * Pittsburgh PA 15213-3890 ! 46: * ! 47: * any improvements or extensions that they make and grant Carnegie Mellon ! 48: * the rights to redistribute these changes. ! 49: */ ! 50: /* ! 51: * File: kern/machine.c ! 52: * Author: Avadis Tevanian, Jr. ! 53: * Date: 1987 ! 54: * ! 55: * Support for machine independent machine abstraction. ! 56: */ ! 57: ! 58: #include <norma_ether.h> ! 59: #include <cpus.h> ! 60: #include <mach_host.h> ! 61: ! 62: #include <mach/boolean.h> ! 63: #include <mach/kern_return.h> ! 64: #include <mach/mach_types.h> ! 65: #include <mach/machine.h> ! 66: #include <mach/host_info.h> ! 67: #include <kern/counters.h> ! 68: #include <kern/ipc_host.h> ! 69: #include <kern/host.h> ! 70: #include <kern/lock.h> ! 71: #include <kern/processor.h> ! 72: #include <kern/queue.h> ! 73: #include <kern/sched.h> ! 74: #include <kern/task.h> ! 75: #include <kern/thread.h> ! 76: #include <machine/machspl.h> /* for splsched */ ! 77: #include <sys/reboot.h> ! 78: ! 79: ! 80: ! 81: /* ! 82: * Exported variables: ! 83: */ ! 84: ! 85: struct machine_info machine_info; ! 86: struct machine_slot machine_slot[NCPUS]; ! 87: ! 88: queue_head_t action_queue; /* assign/shutdown queue */ ! 89: decl_simple_lock_data(,action_lock); ! 90: ! 91: /* ! 92: * xxx_host_info: ! 93: * ! 94: * Return the host_info structure. This routine is exported to the ! 95: * user level. ! 96: */ ! 97: kern_return_t xxx_host_info(task, info) ! 98: task_t task; ! 99: machine_info_t info; ! 100: { ! 101: #ifdef lint ! 102: task++; ! 103: #endif /* lint */ ! 104: *info = machine_info; ! 105: return(KERN_SUCCESS); ! 106: } ! 107: ! 108: /* ! 109: * xxx_slot_info: ! 110: * ! 111: * Return the slot_info structure for the specified slot. This routine ! 112: * is exported to the user level. ! 113: */ ! 114: kern_return_t xxx_slot_info(task, slot, info) ! 115: task_t task; ! 116: int slot; ! 117: machine_slot_t info; ! 118: { ! 119: #ifdef lint ! 120: task++; ! 121: #endif /* lint */ ! 122: if ((slot < 0) || (slot >= NCPUS)) ! 123: return(KERN_INVALID_ARGUMENT); ! 124: *info = machine_slot[slot]; ! 125: return(KERN_SUCCESS); ! 126: } ! 127: ! 128: /* ! 129: * xxx_cpu_control: ! 130: * ! 131: * Support for user control of cpus. The user indicates which cpu ! 132: * he is interested in, and whether or not that cpu should be running. ! 133: */ ! 134: kern_return_t xxx_cpu_control(task, cpu, runnable) ! 135: task_t task; ! 136: int cpu; ! 137: boolean_t runnable; ! 138: { ! 139: #ifdef lint ! 140: task++; cpu++; runnable++; ! 141: #endif /* lint */ ! 142: return(KERN_FAILURE); ! 143: } ! 144: ! 145: /* ! 146: * cpu_up: ! 147: * ! 148: * Flag specified cpu as up and running. Called when a processor comes ! 149: * online. ! 150: */ ! 151: void cpu_up(cpu) ! 152: int cpu; ! 153: { ! 154: register struct machine_slot *ms; ! 155: register processor_t processor; ! 156: register spl_t s; ! 157: ! 158: processor = cpu_to_processor(cpu); ! 159: pset_lock(&default_pset); ! 160: s = splsched(); ! 161: processor_lock(processor); ! 162: #if NCPUS > 1 ! 163: init_ast_check(processor); ! 164: #endif /* NCPUS > 1 */ ! 165: ms = &machine_slot[cpu]; ! 166: ms->running = TRUE; ! 167: machine_info.avail_cpus++; ! 168: pset_add_processor(&default_pset, processor); ! 169: processor->state = PROCESSOR_RUNNING; ! 170: processor_unlock(processor); ! 171: splx(s); ! 172: pset_unlock(&default_pset); ! 173: } ! 174: ! 175: /* ! 176: * cpu_down: ! 177: * ! 178: * Flag specified cpu as down. Called when a processor is about to ! 179: * go offline. ! 180: */ ! 181: void cpu_down(cpu) ! 182: int cpu; ! 183: { ! 184: register struct machine_slot *ms; ! 185: register processor_t processor; ! 186: register spl_t s; ! 187: ! 188: s = splsched(); ! 189: processor = cpu_to_processor(cpu); ! 190: processor_lock(processor); ! 191: ms = &machine_slot[cpu]; ! 192: ms->running = FALSE; ! 193: machine_info.avail_cpus--; ! 194: /* ! 195: * processor has already been removed from pset. ! 196: */ ! 197: processor->processor_set_next = PROCESSOR_SET_NULL; ! 198: processor->state = PROCESSOR_OFF_LINE; ! 199: processor_unlock(processor); ! 200: splx(s); ! 201: } ! 202: ! 203: #if NCPUS > 1 ! 204: /* ! 205: * processor_request_action - common internals of processor_assign ! 206: * and processor_shutdown. If new_pset is null, this is ! 207: * a shutdown, else it's an assign and caller must donate ! 208: * a reference. ! 209: */ ! 210: void ! 211: processor_request_action(processor, new_pset) ! 212: processor_t processor; ! 213: processor_set_t new_pset; ! 214: { ! 215: register processor_set_t pset; ! 216: ! 217: /* ! 218: * Processor must be in a processor set. Must lock its idle lock to ! 219: * get at processor state. ! 220: */ ! 221: pset = processor->processor_set; ! 222: simple_lock(&pset->idle_lock); ! 223: ! 224: /* ! 225: * If the processor is dispatching, let it finish - it will set its ! 226: * state to running very soon. ! 227: */ ! 228: while (*(volatile int *)&processor->state == PROCESSOR_DISPATCHING) ! 229: continue; ! 230: ! 231: /* ! 232: * Now lock the action queue and do the dirty work. ! 233: */ ! 234: simple_lock(&action_lock); ! 235: ! 236: switch (processor->state) { ! 237: case PROCESSOR_IDLE: ! 238: /* ! 239: * Remove from idle queue. ! 240: */ ! 241: queue_remove(&pset->idle_queue, processor, processor_t, ! 242: processor_queue); ! 243: pset->idle_count--; ! 244: ! 245: /* fall through ... */ ! 246: case PROCESSOR_RUNNING: ! 247: /* ! 248: * Put it on the action queue. ! 249: */ ! 250: queue_enter(&action_queue, processor, processor_t, ! 251: processor_queue); ! 252: ! 253: /* fall through ... */ ! 254: case PROCESSOR_ASSIGN: ! 255: /* ! 256: * And ask the action_thread to do the work. ! 257: */ ! 258: ! 259: if (new_pset == PROCESSOR_SET_NULL) { ! 260: processor->state = PROCESSOR_SHUTDOWN; ! 261: } ! 262: else { ! 263: assert(processor->state != PROCESSOR_ASSIGN); ! 264: processor->state = PROCESSOR_ASSIGN; ! 265: processor->processor_set_next = new_pset; ! 266: } ! 267: break; ! 268: ! 269: default: ! 270: printf("state: %d\n", processor->state); ! 271: panic("processor_request_action: bad state"); ! 272: } ! 273: simple_unlock(&action_lock); ! 274: simple_unlock(&pset->idle_lock); ! 275: ! 276: thread_wakeup((event_t)&action_queue); ! 277: } ! 278: ! 279: #if MACH_HOST ! 280: /* ! 281: * processor_assign() changes the processor set that a processor is ! 282: * assigned to. Any previous assignment in progress is overridden. ! 283: * Synchronizes with assignment completion if wait is TRUE. ! 284: */ ! 285: kern_return_t ! 286: processor_assign(processor, new_pset, wait) ! 287: processor_t processor; ! 288: processor_set_t new_pset; ! 289: boolean_t wait; ! 290: { ! 291: spl_t s; ! 292: ! 293: /* ! 294: * Check for null arguments. ! 295: * XXX Can't assign master processor. ! 296: */ ! 297: if (processor == PROCESSOR_NULL || new_pset == PROCESSOR_SET_NULL || ! 298: processor == master_processor) { ! 299: return(KERN_INVALID_ARGUMENT); ! 300: } ! 301: ! 302: /* ! 303: * Get pset reference to donate to processor_request_action. ! 304: */ ! 305: pset_reference(new_pset); ! 306: ! 307: /* ! 308: * Check processor status. ! 309: * If shutdown or being shutdown, can`t reassign. ! 310: * If being assigned, wait for assignment to finish. ! 311: */ ! 312: Retry: ! 313: s = splsched(); ! 314: processor_lock(processor); ! 315: if(processor->state == PROCESSOR_OFF_LINE || ! 316: processor->state == PROCESSOR_SHUTDOWN) { ! 317: /* ! 318: * Already shutdown or being shutdown -- Can't reassign. ! 319: */ ! 320: processor_unlock(processor); ! 321: (void) splx(s); ! 322: pset_deallocate(new_pset); ! 323: return(KERN_FAILURE); ! 324: } ! 325: ! 326: if (processor->state == PROCESSOR_ASSIGN) { ! 327: assert_wait((event_t) processor, TRUE); ! 328: processor_unlock(processor); ! 329: splx(s); ! 330: thread_block_continue((void(*)()) 0); ! 331: goto Retry; ! 332: } ! 333: ! 334: /* ! 335: * Avoid work if processor is already in this processor set. ! 336: */ ! 337: if (processor->processor_set == new_pset) { ! 338: processor_unlock(processor); ! 339: (void) splx(s); ! 340: /* clean up dangling ref */ ! 341: pset_deallocate(new_pset); ! 342: return(KERN_SUCCESS); ! 343: } ! 344: ! 345: /* ! 346: * OK to start processor assignment. ! 347: */ ! 348: processor_request_action(processor, new_pset); ! 349: ! 350: /* ! 351: * Synchronization with completion. ! 352: */ ! 353: if (wait) { ! 354: while (processor->state == PROCESSOR_ASSIGN || ! 355: processor->state == PROCESSOR_SHUTDOWN) { ! 356: assert_wait((event_t)processor, TRUE); ! 357: processor_unlock(processor); ! 358: splx(s); ! 359: thread_block_continue((void (*)()) 0); ! 360: s = splsched(); ! 361: processor_lock(processor); ! 362: } ! 363: } ! 364: processor_unlock(processor); ! 365: splx(s); ! 366: ! 367: return(KERN_SUCCESS); ! 368: } ! 369: ! 370: #else /* MACH_HOST */ ! 371: ! 372: kern_return_t ! 373: processor_assign(processor, new_pset, wait) ! 374: processor_t processor; ! 375: processor_set_t new_pset; ! 376: boolean_t wait; ! 377: { ! 378: #ifdef lint ! 379: processor++; new_pset++; wait++; ! 380: #endif ! 381: return KERN_FAILURE; ! 382: } ! 383: ! 384: #endif /* MACH_HOST */ ! 385: ! 386: /* ! 387: * processor_shutdown() queues a processor up for shutdown. ! 388: * Any assignment in progress is overriden. It does not synchronize ! 389: * with the shutdown (can be called from interrupt level). ! 390: */ ! 391: kern_return_t ! 392: processor_shutdown(processor) ! 393: processor_t processor; ! 394: { ! 395: spl_t s; ! 396: ! 397: if (processor == PROCESSOR_NULL) ! 398: return KERN_INVALID_ARGUMENT; ! 399: ! 400: s = splsched(); ! 401: processor_lock(processor); ! 402: if(processor->state == PROCESSOR_OFF_LINE || ! 403: processor->state == PROCESSOR_SHUTDOWN) { ! 404: /* ! 405: * Already shutdown or being shutdown -- nothing to do. ! 406: */ ! 407: processor_unlock(processor); ! 408: splx(s); ! 409: return(KERN_SUCCESS); ! 410: } ! 411: ! 412: processor_request_action(processor, PROCESSOR_SET_NULL); ! 413: processor_unlock(processor); ! 414: splx(s); ! 415: ! 416: return(KERN_SUCCESS); ! 417: } ! 418: ! 419: /* ! 420: * action_thread() shuts down processors or changes their assignment. ! 421: */ ! 422: void processor_doaction(); /* forward */ ! 423: ! 424: void action_thread_continue() ! 425: { ! 426: register processor_t processor; ! 427: register spl_t s; ! 428: ! 429: while (TRUE) { ! 430: s = splsched(); ! 431: simple_lock(&action_lock); ! 432: while ( !queue_empty(&action_queue)) { ! 433: processor = (processor_t) queue_first(&action_queue); ! 434: queue_remove(&action_queue, processor, processor_t, ! 435: processor_queue); ! 436: simple_unlock(&action_lock); ! 437: (void) splx(s); ! 438: ! 439: processor_doaction(processor); ! 440: ! 441: s = splsched(); ! 442: simple_lock(&action_lock); ! 443: } ! 444: ! 445: assert_wait((event_t) &action_queue, FALSE); ! 446: simple_unlock(&action_lock); ! 447: (void) splx(s); ! 448: counter(c_action_thread_block++); ! 449: thread_block_continue(action_thread_continue); ! 450: } ! 451: } ! 452: ! 453: void action_thread() ! 454: { ! 455: action_thread_continue(); ! 456: /*NOTREACHED*/ ! 457: } ! 458: ! 459: /* ! 460: * processor_doaction actually does the shutdown. The trick here ! 461: * is to schedule ourselves onto a cpu and then save our ! 462: * context back into the runqs before taking out the cpu. ! 463: */ ! 464: #ifdef __GNUC__ ! 465: __volatile__ ! 466: #endif ! 467: void processor_doshutdown(); /* forward */ ! 468: ! 469: void processor_doaction(processor) ! 470: register processor_t processor; ! 471: { ! 472: thread_t this_thread; ! 473: spl_t s; ! 474: register processor_set_t pset; ! 475: #if MACH_HOST ! 476: register processor_set_t new_pset; ! 477: register thread_t thread; ! 478: register thread_t prev_thread = THREAD_NULL; ! 479: boolean_t have_pset_ref = FALSE; ! 480: #endif /* MACH_HOST */ ! 481: ! 482: /* ! 483: * Get onto the processor to shutdown ! 484: */ ! 485: this_thread = current_thread(); ! 486: thread_bind(this_thread, processor); ! 487: thread_block_continue((void (*)()) 0); ! 488: ! 489: pset = processor->processor_set; ! 490: #if MACH_HOST ! 491: /* ! 492: * If this is the last processor in the processor_set, ! 493: * stop all the threads first. ! 494: */ ! 495: pset_lock(pset); ! 496: if (pset->processor_count == 1) { ! 497: /* ! 498: * First suspend all of them. ! 499: */ ! 500: queue_iterate(&pset->threads, thread, thread_t, pset_threads) { ! 501: thread_hold(thread); ! 502: } ! 503: pset->empty = TRUE; ! 504: /* ! 505: * Now actually stop them. Need a pset reference. ! 506: */ ! 507: pset->ref_count++; ! 508: have_pset_ref = TRUE; ! 509: ! 510: Restart_thread: ! 511: prev_thread = THREAD_NULL; ! 512: queue_iterate(&pset->threads, thread, thread_t, pset_threads) { ! 513: thread_reference(thread); ! 514: pset_unlock(pset); ! 515: if (prev_thread != THREAD_NULL) ! 516: thread_deallocate(prev_thread); ! 517: ! 518: /* ! 519: * Only wait for threads still in the pset. ! 520: */ ! 521: thread_freeze(thread); ! 522: if (thread->processor_set != pset) { ! 523: /* ! 524: * It got away - start over. ! 525: */ ! 526: thread_unfreeze(thread); ! 527: thread_deallocate(thread); ! 528: pset_lock(pset); ! 529: goto Restart_thread; ! 530: } ! 531: ! 532: (void) thread_dowait(thread, TRUE); ! 533: prev_thread = thread; ! 534: pset_lock(pset); ! 535: thread_unfreeze(prev_thread); ! 536: } ! 537: } ! 538: pset_unlock(pset); ! 539: ! 540: /* ! 541: * At this point, it is ok to remove the processor from the pset. ! 542: * We can use processor->processor_set_next without locking the ! 543: * processor, since it cannot change while processor->state is ! 544: * PROCESSOR_ASSIGN or PROCESSOR_SHUTDOWN. ! 545: */ ! 546: ! 547: new_pset = processor->processor_set_next; ! 548: ! 549: Restart_pset: ! 550: if (new_pset) { ! 551: /* ! 552: * Reassigning processor. ! 553: */ ! 554: ! 555: if ((integer_t) pset < (integer_t) new_pset) { ! 556: pset_lock(pset); ! 557: pset_lock(new_pset); ! 558: } ! 559: else { ! 560: pset_lock(new_pset); ! 561: pset_lock(pset); ! 562: } ! 563: if (!(new_pset->active)) { ! 564: pset_unlock(new_pset); ! 565: pset_unlock(pset); ! 566: pset_deallocate(new_pset); ! 567: new_pset = &default_pset; ! 568: pset_reference(new_pset); ! 569: goto Restart_pset; ! 570: } ! 571: ! 572: /* ! 573: * Handle remove last / assign first race. ! 574: * Only happens if there is more than one action thread. ! 575: */ ! 576: while (new_pset->empty && new_pset->processor_count > 0) { ! 577: pset_unlock(new_pset); ! 578: pset_unlock(pset); ! 579: while (*(volatile boolean_t *)&new_pset->empty && ! 580: *(volatile int *)&new_pset->processor_count > 0) ! 581: /* spin */; ! 582: goto Restart_pset; ! 583: } ! 584: ! 585: /* ! 586: * Lock the processor. new_pset should not have changed. ! 587: */ ! 588: s = splsched(); ! 589: processor_lock(processor); ! 590: assert(processor->processor_set_next == new_pset); ! 591: ! 592: /* ! 593: * Shutdown may have been requested while this assignment ! 594: * was in progress. ! 595: */ ! 596: if (processor->state == PROCESSOR_SHUTDOWN) { ! 597: processor->processor_set_next = PROCESSOR_SET_NULL; ! 598: pset_unlock(new_pset); ! 599: goto shutdown; /* releases pset reference */ ! 600: } ! 601: ! 602: /* ! 603: * Do assignment, then wakeup anyone waiting for it. ! 604: */ ! 605: pset_remove_processor(pset, processor); ! 606: pset_unlock(pset); ! 607: ! 608: pset_add_processor(new_pset, processor); ! 609: if (new_pset->empty) { ! 610: /* ! 611: * Set all the threads loose. ! 612: * ! 613: * NOTE: this appears to violate the locking ! 614: * order, since the processor lock should ! 615: * be taken AFTER a thread lock. However, ! 616: * thread_setrun (called by thread_release) ! 617: * only takes the processor lock if the ! 618: * processor is idle. The processor is ! 619: * not idle here. ! 620: */ ! 621: queue_iterate(&new_pset->threads, thread, thread_t, ! 622: pset_threads) { ! 623: thread_release(thread); ! 624: } ! 625: new_pset->empty = FALSE; ! 626: } ! 627: processor->processor_set_next = PROCESSOR_SET_NULL; ! 628: processor->state = PROCESSOR_RUNNING; ! 629: thread_wakeup((event_t)processor); ! 630: processor_unlock(processor); ! 631: splx(s); ! 632: pset_unlock(new_pset); ! 633: ! 634: /* ! 635: * Clean up dangling references, and release our binding. ! 636: */ ! 637: pset_deallocate(new_pset); ! 638: if (have_pset_ref) ! 639: pset_deallocate(pset); ! 640: if (prev_thread != THREAD_NULL) ! 641: thread_deallocate(prev_thread); ! 642: thread_bind(this_thread, PROCESSOR_NULL); ! 643: ! 644: thread_block_continue((void (*)()) 0); ! 645: return; ! 646: } ! 647: ! 648: #endif /* MACH_HOST */ ! 649: ! 650: /* ! 651: * Do shutdown, make sure we live when processor dies. ! 652: */ ! 653: if (processor->state != PROCESSOR_SHUTDOWN) { ! 654: printf("state: %d\n", processor->state); ! 655: panic("action_thread -- bad processor state"); ! 656: } ! 657: ! 658: s = splsched(); ! 659: processor_lock(processor); ! 660: ! 661: shutdown: ! 662: pset_remove_processor(pset, processor); ! 663: processor_unlock(processor); ! 664: pset_unlock(pset); ! 665: splx(s); ! 666: ! 667: /* ! 668: * Clean up dangling references, and release our binding. ! 669: */ ! 670: #if MACH_HOST ! 671: if (new_pset != PROCESSOR_SET_NULL) ! 672: pset_deallocate(new_pset); ! 673: if (have_pset_ref) ! 674: pset_deallocate(pset); ! 675: if (prev_thread != THREAD_NULL) ! 676: thread_deallocate(prev_thread); ! 677: #endif /* MACH_HOST */ ! 678: ! 679: thread_bind(this_thread, PROCESSOR_NULL); ! 680: switch_to_shutdown_context(this_thread, ! 681: processor_doshutdown, ! 682: processor); ! 683: ! 684: } ! 685: ! 686: /* ! 687: * Actually do the processor shutdown. This is called at splsched, ! 688: * running on the processor's shutdown stack. ! 689: */ ! 690: ! 691: #ifdef __GNUC__ ! 692: extern __volatile__ void halt_cpu(); ! 693: #endif ! 694: ! 695: #ifdef __GNUC__ ! 696: __volatile__ ! 697: #endif ! 698: void processor_doshutdown(processor) ! 699: register processor_t processor; ! 700: { ! 701: register int cpu = processor->slot_num; ! 702: ! 703: timer_switch(&kernel_timer[cpu]); ! 704: ! 705: /* ! 706: * Ok, now exit this cpu. ! 707: */ ! 708: PMAP_DEACTIVATE_KERNEL(cpu); ! 709: active_threads[cpu] = THREAD_NULL; ! 710: cpu_down(cpu); ! 711: thread_wakeup((event_t)processor); ! 712: halt_cpu(); ! 713: /* ! 714: * The action thread returns to life after the call to ! 715: * switch_to_shutdown_context above, on some other cpu. ! 716: */ ! 717: ! 718: /*NOTREACHED*/ ! 719: } ! 720: #else /* NCPUS > 1 */ ! 721: ! 722: kern_return_t ! 723: processor_assign(processor, new_pset, wait) ! 724: processor_t processor; ! 725: processor_set_t new_pset; ! 726: boolean_t wait; ! 727: { ! 728: #ifdef lint ! 729: processor++; new_pset++; wait++; ! 730: #endif lint ! 731: return(KERN_FAILURE); ! 732: } ! 733: ! 734: #endif /* NCPUS > 1 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.