*
* @APPLE_LICENSE_HEADER_START@
*
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License"). You may not use this file except in compliance with the
- * License. Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
*
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
int cpu)
{
processor_t processor = cpu_to_processor(cpu);
+ processor_set_t pset = &default_pset;
struct machine_slot *ms;
spl_t s;
* Just twiddle our thumbs; we've got nothing better to do
* yet, anyway.
*/
- while (!simple_lock_try(&default_pset.processors_lock))
+ while (!simple_lock_try(&pset->processors_lock))
continue;
s = splsched();
ms = &machine_slot[cpu];
ms->running = TRUE;
machine_info.avail_cpus++;
- pset_add_processor(&default_pset, processor);
+ pset_add_processor(pset, processor);
+ simple_lock(&pset->sched_lock);
+ enqueue_tail(&pset->active_queue, (queue_entry_t)processor);
processor->state = PROCESSOR_RUNNING;
+ simple_unlock(&pset->sched_lock);
processor_unlock(processor);
splx(s);
- simple_unlock(&default_pset.processors_lock);
+ simple_unlock(&pset->processors_lock);
}
/*
processor_t processor,
processor_set_t new_pset)
{
- processor_set_t pset, old_next_pset;
+ processor_set_t pset, old_pset;
/*
* Processor must be in a processor set. Must lock its idle lock to
* get at processor state.
*/
pset = processor->processor_set;
- simple_lock(&pset->idle_lock);
+ simple_lock(&pset->sched_lock);
/*
* If the processor is dispatching, let it finish - it will set its
* state to running very soon.
*/
while (*(volatile int *)&processor->state == PROCESSOR_DISPATCHING) {
- simple_unlock(&pset->idle_lock);
- simple_lock(&pset->idle_lock);
+ simple_unlock(&pset->sched_lock);
+
+ simple_lock(&pset->sched_lock);
}
+ assert( processor->state == PROCESSOR_IDLE ||
+ processor->state == PROCESSOR_RUNNING ||
+ processor->state == PROCESSOR_ASSIGN );
+
/*
* Now lock the action queue and do the dirty work.
*/
simple_lock(&processor_action_lock);
- switch (processor->state) {
-
- case PROCESSOR_IDLE:
- /*
- * Remove from idle queue.
- */
- queue_remove(&pset->idle_queue, processor,
- processor_t, processor_queue);
+ if (processor->state == PROCESSOR_IDLE) {
+ remqueue(&pset->idle_queue, (queue_entry_t)processor);
pset->idle_count--;
+ }
+ else
+ if (processor->state == PROCESSOR_RUNNING)
+ remqueue(&pset->active_queue, (queue_entry_t)processor);
- /* fall through ... */
- case PROCESSOR_RUNNING:
- /*
- * Put it on the action queue.
- */
- queue_enter(&processor_action_queue, processor,
- processor_t,processor_queue);
-
- /* Fall through ... */
- case PROCESSOR_ASSIGN:
- /*
- * And ask the action_thread to do the work.
- */
+ if (processor->state != PROCESSOR_ASSIGN)
+ enqueue_tail(&processor_action_queue, (queue_entry_t)processor);
- if (new_pset == PROCESSOR_SET_NULL) {
- processor->state = PROCESSOR_SHUTDOWN;
- old_next_pset = PROCESSOR_SET_NULL;
- } else {
- processor->state = PROCESSOR_ASSIGN;
- old_next_pset = processor->processor_set_next;
- processor->processor_set_next = new_pset;
- }
- break;
-
- default:
- printf("state: %d\n", processor->state);
- panic("processor_request_action: bad state");
+ /*
+ * And ask the action_thread to do the work.
+ */
+ if (new_pset != PROCESSOR_SET_NULL) {
+ processor->state = PROCESSOR_ASSIGN;
+ old_pset = processor->processor_set_next;
+ processor->processor_set_next = new_pset;
+ }
+ else {
+ processor->state = PROCESSOR_SHUTDOWN;
+ old_pset = PROCESSOR_SET_NULL;
}
- if (processor_action_active == FALSE) {
- processor_action_active = TRUE;
- simple_unlock(&processor_action_lock);
- simple_unlock(&pset->idle_lock);
- processor_unlock(processor);
- thread_call_enter(processor_action_call);
- processor_lock(processor);
- } else {
+ simple_unlock(&pset->sched_lock);
+
+ if (processor_action_active) {
simple_unlock(&processor_action_lock);
- simple_unlock(&pset->idle_lock);
+
+ return (old_pset);
}
- return (old_next_pset);
+ processor_action_active = TRUE;
+ simple_unlock(&processor_action_lock);
+
+ processor_unlock(processor);
+
+ thread_call_enter(processor_action_call);
+ processor_lock(processor);
+
+ return (old_pset);
}
kern_return_t
s = splsched();
processor_lock(processor);
- if ((processor->state == PROCESSOR_OFF_LINE) ||
- (processor->state == PROCESSOR_SHUTDOWN)) {
+ if ( processor->state == PROCESSOR_OFF_LINE ||
+ processor->state == PROCESSOR_SHUTDOWN ) {
/*
* Already shutdown or being shutdown -- nothing to do.
*/
return (KERN_SUCCESS);
}
- (void) processor_request_action(processor, PROCESSOR_SET_NULL);
+ processor_request_action(processor, PROCESSOR_SET_NULL);
assert_wait((event_t)processor, THREAD_UNINT);
processor_unlock(processor);
splx(s);
- thread_block((void (*)(void)) 0);
+ thread_block(THREAD_CONTINUE_NULL);
return (KERN_SUCCESS);
}
simple_lock(&processor_action_lock);
while (!queue_empty(&processor_action_queue)) {
- processor = (processor_t) queue_first(&processor_action_queue);
- queue_remove(&processor_action_queue, processor,
- processor_t, processor_queue);
+ processor = (processor_t)dequeue_head(&processor_action_queue);
simple_unlock(&processor_action_lock);
splx(s);
* Get onto the processor to shutdown
*/
thread_bind(self, processor);
- thread_block((void (*)(void)) 0);
+ thread_block(THREAD_CONTINUE_NULL);
pset = processor->processor_set;
simple_lock(&pset->processors_lock);
s = splsched();
thread_lock(thread);
- thread->state |= TH_RUN;
- _mk_sp_thread_unblock(thread);
- (void)rem_runq(thread);
machine_wake_thread = thread;
+ thread_go_locked(thread, THREAD_AWAKENED);
+ (void)rem_runq(thread);
thread_unlock(thread);
splx(s);
self->continuation = 0;
old_thread = switch_to_shutdown_context(self,
processor_doshutdown, processor);
+ if (processor != current_processor())
+ timer_call_shutdown(processor);
thread_dispatch(old_thread);
thread_wakeup((event_t)processor);
splx(s);
* OK, now exit this cpu.
*/
PMAP_DEACTIVATE_KERNEL(cpu);
- cpu_data[cpu].active_thread = THREAD_NULL;
- active_kloaded[cpu] = THR_ACT_NULL;
+ thread_machine_set_current(processor->idle_thread);
cpu_down(cpu);
cpu_sleep();
panic("zombie processor");