コード例 #1
0
ファイル: machine.c プロジェクト: wzw19890321/xnu-1
/*
 * Called with interrupts disabled.
 */
void
processor_doshutdown(
	processor_t			processor)
{
	thread_t			old_thread, self = current_thread();
	processor_t			prev;
	processor_set_t			pset;

	/*
	 *	Get onto the processor to shutdown
	 */
	prev = thread_bind(processor);
	thread_block(THREAD_CONTINUE_NULL);

	assert(processor->state == PROCESSOR_SHUTDOWN);

#if CONFIG_DTRACE
	if (dtrace_cpu_state_changed_hook)
		(*dtrace_cpu_state_changed_hook)(processor->cpu_id, FALSE);
#endif

	ml_cpu_down();

#if HIBERNATION
	if (processor_avail_count < 2) {
		hibernate_vm_lock();
		hibernate_vm_unlock();
	}
#endif

	pset = processor->processor_set;
	pset_lock(pset);
	processor->state = PROCESSOR_OFF_LINE;
	--pset->online_processor_count;
	(void)hw_atomic_sub(&processor_avail_count, 1);
	commpage_update_active_cpus();
	SCHED(processor_queue_shutdown)(processor);
	/* pset lock dropped */

	/*
	 * Continue processor shutdown in shutdown context.
	 *
	 * We save the current context in machine_processor_shutdown in such a way
	 * that when this thread is next invoked it will return from here instead of
	 * from the machine_switch_context() in thread_invoke like a normal context switch.
	 *
	 * As such, 'old_thread' is neither the idle thread nor the current thread - it's whatever
	 * thread invoked back to this one. (Usually, it's another processor's idle thread.)
	 *
	 * TODO: Make this a real thread_run of the idle_thread, so we don't have to keep this in sync
	 * with thread_invoke.
	 */
	thread_bind(prev);
	old_thread = machine_processor_shutdown(self, processor_offline, processor);

	thread_dispatch(old_thread, self);
}
コード例 #2
0
ファイル: posixtime.c プロジェクト: rohsaini/mkunity
/*
 * Adjust the Universal (Posix) time gradually.
 */
kern_return_t
host_adjust_time(
	host_t		host,
	time_value_t	newadj,
	time_value_t	*oldadj)	/* OUT */
{
	time_value_t	oadj;
	integer_t	ndelta;
	spl_t		s;

	if (host == HOST_NULL)
		return (KERN_INVALID_HOST);

	ndelta = (newadj.seconds * 1000000) + newadj.microseconds;

#if	NCPUS > 1
	thread_bind(current_thread(), master_processor);
	mp_disable_preemption();
	if (current_processor() != master_processor) {
		mp_enable_preemption();
		thread_block((void (*)(void)) 0);
	} else {
		mp_enable_preemption();
	}
#endif	/* NCPUS > 1 */

	s = splclock();
	oadj.seconds = timedelta / 1000000;
	oadj.microseconds = timedelta % 1000000;
	if (timedelta == 0) {
		if (ndelta > bigadj)
			tickdelta = 10 * tickadj;
		else
			tickdelta = tickadj;
	}
	if (ndelta % tickdelta)
		ndelta = ndelta / tickdelta * tickdelta;
	timedelta = ndelta;
	splx(s);

#if	NCPUS > 1
	thread_bind(current_thread(), PROCESSOR_NULL);
#endif	/* NCPUS > 1 */

	*oldadj = oadj;

	return (KERN_SUCCESS);
}
コード例 #3
0
ファイル: chud_thread.c プロジェクト: JackieXie168/xnu
__private_extern__ kern_return_t
chudxnu_unbind_thread(thread_t thread, __unused int options)
{
	if(thread == current_thread())
		thread_bind(PROCESSOR_NULL);
    return KERN_SUCCESS;
}
コード例 #4
0
ファイル: machine.c プロジェクト: JackieXie168/xnu
/*
 * Called with interrupts disabled.
 */
void
processor_doshutdown(
	processor_t			processor)
{
	thread_t			old_thread, self = current_thread();
	processor_t			prev;
	processor_set_t			pset;

	/*
	 *	Get onto the processor to shutdown
	 */
	prev = thread_bind(processor);
	thread_block(THREAD_CONTINUE_NULL);

	assert(processor->state == PROCESSOR_SHUTDOWN);

#if CONFIG_DTRACE
	if (dtrace_cpu_state_changed_hook)
		(*dtrace_cpu_state_changed_hook)(processor->cpu_id, FALSE);
#endif

	ml_cpu_down();

#if HIBERNATION
	if (processor_avail_count < 2) {
		hibernate_vm_lock();
		hibernate_vm_unlock();
	}
#endif

	pset = processor->processor_set;
	pset_lock(pset);
	processor->state = PROCESSOR_OFF_LINE;
	--pset->online_processor_count;
	(void)hw_atomic_sub(&processor_avail_count, 1);
	commpage_update_active_cpus();
	SCHED(processor_queue_shutdown)(processor);
	/* pset lock dropped */

	/*
	 *	Continue processor shutdown in shutdown context.
	 */
	thread_bind(prev);
	old_thread = machine_processor_shutdown(self, processor_offline, processor);

	thread_dispatch(old_thread, self);
}
コード例 #5
0
ファイル: chud_thread.c プロジェクト: OpenDarwin-CVS/SEDarwin
__private_extern__
kern_return_t chudxnu_bind_current_thread(int cpu)
{
    if(cpu>=0 && cpu<chudxnu_avail_cpu_count()) { /* make sure cpu # is sane */
        thread_bind(current_thread(), processor_ptr[cpu]);
        thread_block((void (*)(void)) 0);
        return KERN_SUCCESS;
    } else {
        return KERN_FAILURE;
    }
}
コード例 #6
0
ファイル: posixtime.c プロジェクト: rohsaini/mkunity
/*
 * Set the Universal (Posix) time. Privileged call.
 */
kern_return_t
host_set_time(
	host_t		host,
	time_value_t	new_time)
{
	spl_t	s;

	if (host == HOST_NULL)
		return(KERN_INVALID_HOST);

#if	NCPUS > 1
	thread_bind(current_thread(), master_processor);
	mp_disable_preemption();
	if (current_processor() != master_processor) {
		mp_enable_preemption();
		thread_block((void (*)(void)) 0);
	} else {
		mp_enable_preemption();
	}
#endif	/* NCPUS > 1 */

	s = splhigh();
	time = new_time;
	update_mapped_time(&time);
#if	PTIME_MACH_RT
	rtc_gettime_interrupts_disabled((tvalspec_t *)&last_utime_tick);
#endif	/* PTIME_MACH_RT */
#if 0
	(void)bbc_settime((time_value_t *)&time);
#endif
	splx(s);

#if	NCPUS > 1
	thread_bind(current_thread(), PROCESSOR_NULL);
#endif	/* NCPUS > 1 */

	return (KERN_SUCCESS);
}
コード例 #7
0
ファイル: thread.c プロジェクト: jrepan/rhombus
struct thread *thread_send(struct thread *image, pid_t target, portid_t port, struct msg *msg) {
	struct process *p_targ;
	struct thread *new_image;

	/* find target process */
	p_targ = process_get(target);

	/* check process */
	if (!p_targ || !p_targ->entry) {
		return image;
	}

	/* create new thread */
	new_image = thread_alloc();
	thread_bind(new_image, p_targ);

	new_image->ds      = 0x23;
	new_image->cs      = 0x1B;
	new_image->ss      = 0x23;
	new_image->eflags  = 0;
	new_image->useresp = new_image->stack + SEGSZ;
	new_image->proc    = p_targ;
	new_image->eip     = p_targ->entry;

	/* set up registers in new thread */
	new_image->ebx     = 0;
	new_image->ecx     = (msg) ? msg->count : 0;
	new_image->edx     = port;
	new_image->esi     = (image) ? image->proc->pid : 0;
	new_image->edi     = 0;
	new_image->msg     = msg;

	/* set new thread's user id */
	new_image->user = (!image || p_targ->user) ? p_targ->user : image->user;

	/* insert new thread into scheduler */
	schedule_insert(new_image);

	/* return new thread */
	return new_image;
}
コード例 #8
0
ファイル: chud_thread.c プロジェクト: JackieXie168/xnu
/*
 * This method will bind a given thread to the requested CPU starting at the
 * next time quantum.  If the thread is the current thread, this method will
 * force a thread_block().  The result is that if you call this method on the
 * current thread, you will be on the requested CPU when this method returns.
 */
__private_extern__ kern_return_t
chudxnu_bind_thread(thread_t thread, int cpu, __unused int options)
{
    processor_t proc = NULL;

	if(cpu < 0 || (unsigned int)cpu >= real_ncpus) // sanity check
		return KERN_FAILURE;

	// temporary restriction until after phase 2 of the scheduler
	if(thread != current_thread())
		return KERN_FAILURE; 
	
	proc = cpu_to_processor(cpu);

	/* 
	 * Potentially racey, but mainly to prevent bind to shutdown
	 * processor.
	 */
	if(proc && !(proc->state == PROCESSOR_OFF_LINE) &&
			!(proc->state == PROCESSOR_SHUTDOWN)) {
		
		thread_bind(proc);

		/*
		 * If we're trying to bind the current thread, and
		 * we're not on the target cpu, and not at interrupt
		 * context, block the current thread to force a
		 * reschedule on the target CPU.
		 */
		if(thread == current_thread() && 
			!ml_at_interrupt_context() && cpu_number() != cpu) {
			(void)thread_block(THREAD_CONTINUE_NULL);
		}
		return KERN_SUCCESS;
	}
    return KERN_FAILURE;
}
コード例 #9
0
ファイル: machine.c プロジェクト: rohsaini/mkunity
void
processor_doaction(
	processor_t	processor)
{
	thread_t			this_thread;
	spl_t				s;
	register processor_set_t	pset;
#if	MACH_HOST
	register processor_set_t	new_pset;
	register thread_t		thread;
	register thread_t		prev_thread = THREAD_NULL;
	thread_act_t			thr_act;
	boolean_t			have_pset_ref = FALSE;
#endif	/* MACH_HOST */

	/*
	 *	Get onto the processor to shutdown
	 */
	this_thread = current_thread();
	thread_bind(this_thread, processor);
	thread_block((void (*)(void)) 0);

	pset = processor->processor_set;
#if	MACH_HOST
	/*
	 *	If this is the last processor in the processor_set,
	 *	stop all the threads first.
	 */
	pset_lock(pset);
	if (pset->processor_count == 1) {
		thread = (thread_t) queue_first(&pset->threads);
		prev_thread = THREAD_NULL;
		pset->ref_count++;
		have_pset_ref = TRUE;
		pset->empty = TRUE;

		/*
		 * loop through freezing the processor set assignment
		 * and reference counting the threads;
		 */
		while (!queue_end(&pset->threads, (queue_entry_t) thread)) {
		    thread_reference(thread);
		    pset_unlock(pset);

		    /*
		     * Freeze the thread on the processor set.
		     * If it's moved, just release the reference.
		     * Get the next thread in the processor set list
		     * from the last one which was frozen.
		     */
		    if( thread_stop_freeze(thread, pset) )
		        prev_thread = thread;
		    else
			thread_deallocate(thread);

		    pset_lock(pset);
		    if( prev_thread != THREAD_NULL ) 
		        thread = (thread_t)queue_next(&prev_thread->pset_threads);
		    else
			thread = (thread_t) queue_first(&pset->threads);
		}

		/*
		 * Remove the processor from the set so that when the threads
		 * are unstopped below the ones blocked in the kernel don't
		 * start running again.
		 */
		s = splsched();
		processor_lock(processor);
		pset_remove_processor(pset, processor);

		/*
		 * Prevent race with another processor being added to the set
		 * See code after Restart_pset:
		 *   while(new_pset->empty && new_pset->processor_count > 0)
		 *
		 * ... it tests for the condition where a new processor is
		 * added to the set while the last one is still being removed.
		 */
		pset->processor_count++;	/* block new processors being added */
		assert( pset->processor_count == 1 );

		/*
		 * Release the thread assignment locks, unstop the threads and
		 * release the thread references which were taken above.
		 */
		thread = (thread_t) queue_first(&pset->threads);
		while( !queue_empty( &pset->threads) && (thread != THREAD_NULL) ) {
		    prev_thread = thread;
		    if( queue_end(&pset->threads, (queue_entry_t) thread) )
			thread = THREAD_NULL;
		    else
		        thread = (thread_t) queue_next(&prev_thread->pset_threads);
		    pset_unlock(pset);
		    thread_unfreeze(prev_thread);
		    thread_unstop(prev_thread);
		    thread_deallocate(prev_thread);
		    pset_lock(pset);
		}
		/*
		 * allow a processor to be added to the empty pset
		 */
		pset->processor_count--;
	}
	else { 
		/* not last processor in set */
#endif	/* MACH_HOST */
		/*
		 * At this point, it is ok to rm the processor from the pset.
		 */
		s = splsched();
		processor_lock(processor);
		pset_remove_processor(pset, processor);
#if	MACH_HOST
	}
	pset_unlock(pset);

	/*
	 *	Copy the next pset pointer into a local variable and clear
	 *	it because we are taking over its reference.
	 */
	new_pset = processor->processor_set_next;
	processor->processor_set_next = PROCESSOR_SET_NULL;

	if (processor->state == PROCESSOR_ASSIGN) {

Restart_pset:
	    /*
	     *	Nasty problem: we want to lock the target pset, but
	     *	we have to enable interrupts to do that which requires
	     *  dropping the processor lock.  While the processor
	     *  is unlocked, it could be reassigned or shutdown.
	     */
	    processor_unlock(processor);
	    splx(s);

	    /*
	     *  Lock target pset and handle remove last / assign first race.
	     *	Only happens if there is more than one action thread.
	     */
	    pset_lock(new_pset);
	    while (new_pset->empty && new_pset->processor_count > 0) {
		pset_unlock(new_pset);
		while (*(volatile boolean_t *)&new_pset->empty &&
		       *(volatile int *)&new_pset->processor_count > 0)
			/* spin */;
		pset_lock(new_pset);
	    }

	    /*
	     *	Finally relock the processor and see if something changed.
	     *	The only possibilities are assignment to a different pset
	     *	and shutdown.
	     */
	    s = splsched();
	    processor_lock(processor);

	    if (processor->state == PROCESSOR_SHUTDOWN) {
		pset_unlock(new_pset);
		goto shutdown; /* will release pset reference */
	    }

	    if (processor->processor_set_next != PROCESSOR_SET_NULL) {
		/*
		 *	Processor was reassigned.  Drop the reference
		 *	we have on the wrong new_pset, and get the
		 *	right one.  Involves lots of lock juggling.
		 */
		processor_unlock(processor);
		splx(s);
		pset_unlock(new_pset);
		pset_deallocate(new_pset);
		s = splsched();
	        processor_lock(processor);
		new_pset = processor->processor_set_next;
		processor->processor_set_next = PROCESSOR_SET_NULL;
		goto Restart_pset;
	    }

	    /*
	     *	If the pset has been deactivated since the operation
	     *	was requested, redirect to the default pset.
	     */
	    if (!(new_pset->active)) {
		pset_unlock(new_pset);
		pset_deallocate(new_pset);
		new_pset = &default_pset;
		pset_lock(new_pset);
		new_pset->ref_count++;
	    }

	    /*
	     *	Do assignment, then wakeup anyone waiting for it.
	     *	Finally context switch to have it take effect.
	     */
	    pset_add_processor(new_pset, processor);
	    if (new_pset->empty) {
		/*
		 *	Set all the threads loose
		 */
		thread = (thread_t) queue_first(&new_pset->threads);
		while (!queue_end(&new_pset->threads,(queue_entry_t)thread)) {
		    thr_act = thread_lock_act(thread);
		    thread_release(thread->top_act);
		    act_unlock_thread(thr_act);
		    thread = (thread_t) queue_next(&thread->pset_threads);
		}
		new_pset->empty = FALSE;
	    }
	    processor->processor_set_next = PROCESSOR_SET_NULL;
	    processor->state = PROCESSOR_RUNNING;
	    thread_wakeup((event_t)processor);
	    processor_unlock(processor);
	    splx(s);
	    pset_unlock(new_pset);

	    /*
	     *	Clean up dangling references, and release our binding.
	     */
	    pset_deallocate(new_pset);
	    if (have_pset_ref)
		pset_deallocate(pset);
	    if (prev_thread != THREAD_NULL)
		thread_deallocate(prev_thread);
	    thread_bind(this_thread, PROCESSOR_NULL);

	    thread_block((void (*)(void)) 0);
	    return;
	}

shutdown:
#endif	/* MACH_HOST */
	
	/*
	 *	Do shutdown, make sure we live when processor dies.
	 */
	if (processor->state != PROCESSOR_SHUTDOWN) {
		printf("state: %d\n", processor->state);
	    	panic("action_thread -- bad processor state");
	}
	processor_unlock(processor);
	/*
	 *	Clean up dangling references, and release our binding.
	 */
#if	MACH_HOST
	if (new_pset != PROCESSOR_SET_NULL)
		pset_deallocate(new_pset);
	if (have_pset_ref)
		pset_deallocate(pset);
	if (prev_thread != THREAD_NULL)
		thread_deallocate(prev_thread);
#endif	/* MACH_HOST */

	thread_bind(this_thread, PROCESSOR_NULL);
	switch_to_shutdown_context(this_thread,
				   processor_doshutdown,
				   processor);
	splx(s);
}
コード例 #10
0
ファイル: startup.c プロジェクト: ctos/bpi
/*
 * Now running in a thread.  Create the rest of the kernel threads
 * and the bootstrap task.
 */
void start_kernel_threads()
{
	register int	i;

	/*
	 *	Create the idle threads and the other
	 *	service threads.
	 */
	for (i = 0; i < NCPUS; i++) {
	    if (machine_slot[i].is_cpu) {
		thread_t	th;

		(void) thread_create(kernel_task, &th);
		thread_bind(th, cpu_to_processor(i));
		thread_start(th, idle_thread);
		thread_doswapin(th);
		(void) thread_resume(th);
	    }
	}

	(void) kernel_thread(kernel_task, reaper_thread, (char *) 0);
	(void) kernel_thread(kernel_task, swapin_thread, (char *) 0);
	(void) kernel_thread(kernel_task, sched_thread, (char *) 0);

#if	NCPUS > 1
	/*
	 *	Create the shutdown thread.
	 */
	(void) kernel_thread(kernel_task, action_thread, (char *) 0);

	/*
	 *	Allow other CPUs to run.
	 */
	start_other_cpus();
#endif	/* NCPUS > 1 */

	/*
	 *	Create the device service.
	 */
	device_service_create();

	/*
	 * 	Initialize kernel task's creation time.
	 * When we created the kernel task in task_init, the mapped
	 * time was not yet available.  Now, last thing before starting
	 * the user bootstrap, record the current time as the kernel
	 * task's creation time.
	 */
	record_time_stamp (&kernel_task->creation_time);

	/*
	 *	Start the user bootstrap.
	 */
	bootstrap_create();

#if	XPR_DEBUG
	xprinit();		/* XXX */
#endif	/* XPR_DEBUG */

	/*
	 *	Become the pageout daemon.
	 */
	(void) spl0();
	vm_pageout();
	/*NOTREACHED*/
}
コード例 #11
0
ファイル: init.c プロジェクト: asegid/rhombus
struct thread *init(struct multiboot *mboot, uint32_t mboot_magic) {
	struct process *idle, *init;
	struct module *module;
	struct memory_map *mem_map;
	size_t mem_map_count, i, addr;
	uintptr_t boot_image_size;
	void *boot_image;
	struct elf32_ehdr *init_image;
	struct elf32_ehdr *dl_image;

	/* initialize debugging output */
	debug_init();
	debug_printf("Rhombus Operating System Kernel v0.8a\n");

	/* check multiboot header */
	if (mboot_magic != 0x2BADB002) {
		debug_panic("bootloader is not multiboot compliant");
	}

	/* touch pages for the kernel heap */
	for (i = KSPACE; i < KERNEL_HEAP_END; i += SEGSZ) {
		page_touch(i);
	}

	/* identity map kernel boot frames */
	for (i = KSPACE + KERNEL_BOOT; i < KSPACE + KERNEL_BOOT_END; i += PAGESZ) {
		page_set(i, page_fmt(i - KSPACE, PF_PRES | PF_RW));
	}

	/* parse the multiboot memory map to find the size of memory */
	mem_map       = (void*) (mboot->mmap_addr + KSPACE);
	mem_map_count = mboot->mmap_length / sizeof(struct memory_map);

	for (i = 0; i < mem_map_count; i++) {
		if (mem_map[i].type == 1 && mem_map[i].base_addr_low <= 0x100000) {
			for (addr = 0; addr < mem_map[i].length_low; addr += PAGESZ) {
				frame_add(mem_map[i].base_addr_low + addr);
			}
		}
	}

	/* bootstrap process 0 (idle) */
	idle = process_alloc();
	idle->space = cpu_get_cr3();
	idle->user  = 0;

	/* fork process 1 (init) and switch */
	init = process_clone(idle, NULL);
	process_switch(init);

	/* get multiboot module information */
	if (mboot->mods_count < 3) {
		if (mboot->mods_count < 2) {
			if (mboot->mods_count < 1) {
				debug_panic("no boot or init or dl modules found");
			}
			else {
				debug_panic("no boot or dl modules found");
			}
		}
		else {
			debug_panic("no dl module found");
		}
	}
	module     = (void*) (mboot->mods_addr + KSPACE);
	init_image = (void*) (module[0].mod_start + KSPACE);
	boot_image = (void*) (module[1].mod_start + KSPACE);
	dl_image   = (void*) (module[2].mod_start + KSPACE);
	boot_image_size = module[1].mod_end - module[1].mod_start;

	/* move boot image to BOOT_IMAGE in userspace */
	mem_alloc(BOOT_IMAGE, boot_image_size, PF_PRES | PF_USER | PF_RW);
	memcpy((void*) BOOT_IMAGE, boot_image, boot_image_size);

	/* bootstrap thread 0 in init */
	thread_bind(init->thread[0], init);
	init->thread[0]->useresp = init->thread[0]->stack + SEGSZ;
	init->thread[0]->esp     = (uintptr_t) &init->thread[0]->num;
	init->thread[0]->ss      = 0x23;
	init->thread[0]->ds      = 0x23;
	init->thread[0]->cs      = 0x1B;
	init->thread[0]->eflags  = cpu_get_eflags() | 0x3200; /* IF, IOPL = 3 */

	/* bootstrap idle thread */
	idle->thread[0] = &__idle_thread;
	__idle_thread.proc = idle;

	/* load dl */
	if (elf_check_file(dl_image)) {
		debug_panic("dl.so is not a valid ELF executable");
	}
	elf_load_file(dl_image);

	/* execute init */
	if (elf_check_file(init_image)) {
		debug_panic("init is not a valid ELF executable");
	}
	elf_load_file(init_image);
	init->thread[0]->eip = init_image->e_entry;

	/* register system calls */
	int_set_handler(SYSCALL_SEND, syscall_send);
	int_set_handler(SYSCALL_DONE, syscall_done);
	int_set_handler(SYSCALL_WHEN, syscall_when);
	int_set_handler(SYSCALL_RIRQ, syscall_rirq);
	int_set_handler(SYSCALL_ALSO, syscall_also);
	int_set_handler(SYSCALL_STAT, syscall_stat);
	int_set_handler(SYSCALL_PAGE, syscall_page);
	int_set_handler(SYSCALL_PHYS, syscall_phys);
	int_set_handler(SYSCALL_FORK, syscall_fork);
	int_set_handler(SYSCALL_EXIT, syscall_exit);
	int_set_handler(SYSCALL_STOP, syscall_stop);
	int_set_handler(SYSCALL_WAKE, syscall_wake);
	int_set_handler(SYSCALL_GPID, syscall_gpid);
	int_set_handler(SYSCALL_TIME, syscall_time);
	int_set_handler(SYSCALL_USER, syscall_user);
	int_set_handler(SYSCALL_AUTH, syscall_auth);
	int_set_handler(SYSCALL_PROC, syscall_proc);
	int_set_handler(SYSCALL_KILL, syscall_kill);
	int_set_handler(SYSCALL_VM86, syscall_vm86);
	int_set_handler(SYSCALL_NAME, syscall_name);
	int_set_handler(SYSCALL_REAP, syscall_reap);

	/* register fault handlers */
	int_set_handler(FAULT_DE, fault_float);
	int_set_handler(FAULT_DB, fault_generic);
	int_set_handler(FAULT_NI, fault_generic);
	int_set_handler(FAULT_BP, fault_generic);
	int_set_handler(FAULT_OF, fault_generic);
	int_set_handler(FAULT_BR, fault_generic);
	int_set_handler(FAULT_UD, fault_generic);
	int_set_handler(FAULT_NM, fault_nomath);
	int_set_handler(FAULT_DF, fault_double);
	int_set_handler(FAULT_CO, fault_float);
	int_set_handler(FAULT_TS, fault_generic);
	int_set_handler(FAULT_NP, fault_generic);
	int_set_handler(FAULT_SS, fault_generic);
	int_set_handler(FAULT_GP, fault_gpf);
	int_set_handler(FAULT_PF, fault_page);
	int_set_handler(FAULT_MF, fault_float);
	int_set_handler(FAULT_AC, fault_generic);
	int_set_handler(FAULT_MC, fault_generic);
	int_set_handler(FAULT_XM, fault_nomath);

	/* start timer (for preemption) */
	timer_set_freq(64);

	/* initialize FPU/MMX/SSE */
	cpu_init_fpu();

	/* drop to usermode, scheduling the next thread */
	debug_printf("dropping to usermode\n");
	return thread_switch(NULL, schedule_next());
}
コード例 #12
0
ファイル: startup.c プロジェクト: androidisbest/xnu-1
/*
 * Now running in a thread.  Kick off other services,
 * invoke user bootstrap, enter pageout loop.
 */
static void
kernel_bootstrap_thread(void)
{
	processor_t		processor = current_processor();

#define kernel_bootstrap_thread_kprintf(x...) /* kprintf("kernel_bootstrap_thread: " x) */
	kernel_bootstrap_thread_log("idle_thread_create");
	/*
	 * Create the idle processor thread.
	 */
	idle_thread_create(processor);

	/*
	 * N.B. Do not stick anything else
	 * before this point.
	 *
	 * Start up the scheduler services.
	 */
	kernel_bootstrap_thread_log("sched_startup");
	sched_startup();

	/*
	 * Thread lifecycle maintenance (teardown, stack allocation)
	 */
	kernel_bootstrap_thread_log("thread_daemon_init");
	thread_daemon_init();

	/* Create kernel map entry reserve */
	vm_kernel_reserved_entry_init();

	/*
	 * Thread callout service.
	 */
	kernel_bootstrap_thread_log("thread_call_initialize");
	thread_call_initialize();

	/*
	 * Remain on current processor as
	 * additional processors come online.
	 */
	kernel_bootstrap_thread_log("thread_bind");
	thread_bind(processor);

	/*
	 * Initialize ipc thread call support.
	 */
	kernel_bootstrap_thread_log("ipc_thread_call_init");
	ipc_thread_call_init();

	/*
	 * Kick off memory mapping adjustments.
	 */
	kernel_bootstrap_thread_log("mapping_adjust");
	mapping_adjust();

	/*
	 *	Create the clock service.
	 */
	kernel_bootstrap_thread_log("clock_service_create");
	clock_service_create();

	/*
	 *	Create the device service.
	 */
	device_service_create();

	kth_started = 1;
		
#if (defined(__i386__) || defined(__x86_64__)) && NCOPY_WINDOWS > 0
	/*
	 * Create and initialize the physical copy window for processor 0
	 * This is required before starting kicking off  IOKit.
	 */
	cpu_physwindow_init(0);
#endif


	
#if MACH_KDP 
	kernel_bootstrap_log("kdp_init");
	kdp_init();
#endif

#if ALTERNATE_DEBUGGER
	alternate_debugger_init();
#endif

#if KPC
	kpc_init();
#endif

#if CONFIG_ECC_LOGGING
	ecc_log_init();
#endif 

#if KPERF
	kperf_bootstrap();
#endif

#if HYPERVISOR
	hv_support_init();
#endif

#if CONFIG_TELEMETRY
	kernel_bootstrap_log("bootprofile_init");
	bootprofile_init();
#endif

#if (defined(__i386__) || defined(__x86_64__)) && CONFIG_VMX
	vmx_init();
#endif

#if (defined(__i386__) || defined(__x86_64__))
	if (kdebug_serial) {
		new_nkdbufs = 1;
		if (trace_typefilter == 0)
			trace_typefilter = 1;
	}
	if (turn_on_log_leaks && !new_nkdbufs)
		new_nkdbufs = 200000;
	if (trace_typefilter)
		start_kern_tracing_with_typefilter(new_nkdbufs,
						   FALSE,
						   trace_typefilter);
	else
		start_kern_tracing(new_nkdbufs, FALSE);
	if (turn_on_log_leaks)
		log_leaks = 1;

#endif

	kernel_bootstrap_log("prng_init");
	prng_cpu_init(master_cpu);

#ifdef	IOKIT
	PE_init_iokit();
#endif

	assert(ml_get_interrupts_enabled() == FALSE);
	(void) spllo();		/* Allow interruptions */

#if (defined(__i386__) || defined(__x86_64__)) && NCOPY_WINDOWS > 0
	/*
	 * Create and initialize the copy window for processor 0
	 * This also allocates window space for all other processors.
	 * However, this is dependent on the number of processors - so this call
	 * must be after IOKit has been started because IOKit performs processor
	 * discovery.
	 */
	cpu_userwindow_init(0);
#endif

#if (!defined(__i386__) && !defined(__x86_64__))
	if (turn_on_log_leaks && !new_nkdbufs)
		new_nkdbufs = 200000;
	if (trace_typefilter)
		start_kern_tracing_with_typefilter(new_nkdbufs, FALSE, trace_typefilter);
	else
		start_kern_tracing(new_nkdbufs, FALSE);
	if (turn_on_log_leaks)
		log_leaks = 1;
#endif

	/*
	 *	Initialize the shared region module.
	 */
	vm_shared_region_init();
	vm_commpage_init();
	vm_commpage_text_init();


#if CONFIG_MACF
	kernel_bootstrap_log("mac_policy_initmach");
	mac_policy_initmach();
#endif

#if CONFIG_SCHED_SFI
	kernel_bootstrap_log("sfi_init");
	sfi_init();
#endif

	/*
	 * Initialize the globals used for permuting kernel
	 * addresses that may be exported to userland as tokens
	 * using VM_KERNEL_ADDRPERM()/VM_KERNEL_ADDRPERM_EXTERNAL().
	 * Force the random number to be odd to avoid mapping a non-zero
	 * word-aligned address to zero via addition.
	 * Note: at this stage we can use the cryptographically secure PRNG
	 * rather than early_random().
	 */
	read_random(&vm_kernel_addrperm, sizeof(vm_kernel_addrperm));
	vm_kernel_addrperm |= 1;
	read_random(&buf_kernel_addrperm, sizeof(buf_kernel_addrperm));
	buf_kernel_addrperm |= 1;
	read_random(&vm_kernel_addrperm_ext, sizeof(vm_kernel_addrperm_ext));
	vm_kernel_addrperm_ext |= 1;

	vm_set_restrictions();



	/*
	 *	Start the user bootstrap.
	 */
#ifdef	MACH_BSD
	bsd_init();
#endif

    /*
     * Get rid of segments used to bootstrap kext loading. This removes
     * the KLD, PRELINK symtab, LINKEDIT, and symtab segments/load commands.
     */
	OSKextRemoveKextBootstrap();

	serial_keyboard_init();		/* Start serial keyboard if wanted */

	vm_page_init_local_q();

	thread_bind(PROCESSOR_NULL);

	/*
	 *	Become the pageout daemon.
	 */
	vm_pageout();
	/*NOTREACHED*/
}
コード例 #13
0
kern_return_t
processor_start(
	processor_t			processor)
{
	processor_set_t		pset;
	thread_t			thread;   
	kern_return_t		result;
	spl_t				s;

	if (processor == PROCESSOR_NULL || processor->processor_set == PROCESSOR_SET_NULL)
		return (KERN_INVALID_ARGUMENT);

	if (processor == master_processor) {
		processor_t		prev;

		prev = thread_bind(processor);
		thread_block(THREAD_CONTINUE_NULL);

		result = cpu_start(processor->cpu_id);

		thread_bind(prev);

		return (result);
	}

	s = splsched();
	pset = processor->processor_set;
	pset_lock(pset);
	if (processor->state != PROCESSOR_OFF_LINE) {
		pset_unlock(pset);
		splx(s);

		return (KERN_FAILURE);
	}

	processor->state = PROCESSOR_START;
	pset_unlock(pset);
	splx(s);

	/*
	 *	Create the idle processor thread.
	 */
	if (processor->idle_thread == THREAD_NULL) {
		result = idle_thread_create(processor);
		if (result != KERN_SUCCESS) {
			s = splsched();
			pset_lock(pset);
			processor->state = PROCESSOR_OFF_LINE;
			pset_unlock(pset);
			splx(s);

			return (result);
		}
	}

	/*
	 *	If there is no active thread, the processor
	 *	has never been started.  Create a dedicated
	 *	start up thread.
	 */
	if (	processor->active_thread == THREAD_NULL		&&
			processor->next_thread == THREAD_NULL		) {
		result = kernel_thread_create((thread_continue_t)processor_start_thread, NULL, MAXPRI_KERNEL, &thread);
		if (result != KERN_SUCCESS) {
			s = splsched();
			pset_lock(pset);
			processor->state = PROCESSOR_OFF_LINE;
			pset_unlock(pset);
			splx(s);

			return (result);
		}

		s = splsched();
		thread_lock(thread);
		thread->bound_processor = processor;
		processor->next_thread = thread;
		thread->state = TH_RUN;
		thread_unlock(thread);
		splx(s);

		thread_deallocate(thread);
	}

	if (processor->processor_self == IP_NULL)
		ipc_processor_init(processor);

	result = cpu_start(processor->cpu_id);
	if (result != KERN_SUCCESS) {
		s = splsched();
		pset_lock(pset);
		processor->state = PROCESSOR_OFF_LINE;
		pset_unlock(pset);
		splx(s);

		return (result);
	}

	ipc_processor_enable(processor);

	return (KERN_SUCCESS);
}
コード例 #14
0
ファイル: startup.c プロジェクト: rohsaini/mkunity
/*
 *	Running in virtual memory, on the interrupt stack.
 *	Does not return.  Dispatches initial thread.
 *
 *	Assumes that master_cpu is set.
 */
void
setup_main(void)
{
	thread_t		startup_thread;

	printf_init();
	panic_init();

	sched_init();
	vm_mem_bootstrap();
	ipc_bootstrap();
	vm_mem_init();
	ipc_init();

	/*
	 * As soon as the virtual memory system is up, we record
	 * that this CPU is using the kernel pmap.
	 */
	PMAP_ACTIVATE_KERNEL(master_cpu);

	init_timers();
	timeout_init();

#if	CDLI > 0
	ns_init();	/* Initialize CDLI */
#endif	/* CDLI > 0 */

	dev_lookup_init();
	timeout_init();
	machine_init();

	machine_info.max_cpus = NCPUS;
	machine_info.memory_size = mem_size;
	machine_info.avail_cpus = 0;
	machine_info.major_version = KERNEL_MAJOR_VERSION;
	machine_info.minor_version = KERNEL_MINOR_VERSION;

#if	XPR_DEBUG
	xprbootstrap();
#endif	/* XPR_DEBUG */

	/*
	 *	Initialize the IPC, task, and thread subsystems.
	 */
	clock_init();
	utime_init();
        ledger_init();
#if	THREAD_SWAPPER
	thread_swapper_init();
#endif	/* THREAD_SWAPPER */
#if	TASK_SWAPPER
	task_swapper_init();
#endif	/* TASK_SWAPPER */
	task_init();
	act_init();
	thread_init();
	subsystem_init();
#if	TASK_SWAPPER
	task_swappable(&realhost, kernel_task, FALSE);
#endif	/* TASK_SWAPPER */
#if	MACH_HOST
	pset_sys_init();
#endif	/* MACH_HOST */

	/*
	 *	Kick off the time-out driven routines by calling
	 *	them the first time.
	 */
	recompute_priorities();
	compute_mach_factor();

	/*
	 *	Initialize the Event Trace Analysis Package.
	 * 	Dynamic Phase: 2 of 2
	 */
	etap_init_phase2();
	
	/*
	 *	Create a kernel thread to start the other kernel
	 *	threads.  Thread_resume (from kernel_thread) calls
	 *	thread_setrun, which may look at current thread;
	 *	we must avoid this, since there is no current thread.
	 */

	/*
	 * Create the thread, and point it at the routine.
	 */
	(void) thread_create_at(kernel_task, &startup_thread,
							start_kernel_threads);
#if	NCPUS > 1 && PARAGON860
	thread_bind(startup_thread, cpu_to_processor(master_cpu));
#endif
	/*
	 * Pretend it is already running, and resume it.
	 * Since it looks as if it is running, thread_resume
	 * will not try to put it on the run queues.
	 *
	 * We can do all of this without locking, because nothing
	 * else is running yet.
	 */
	startup_thread->state |= TH_RUN;
	(void) thread_resume(startup_thread->top_act);

	/*
	 * Start the thread.
	 */
	cpu_launch_first_thread(startup_thread);
	/*NOTREACHED*/
	panic("cpu_launch_first_thread returns!");
}
コード例 #15
0
ファイル: tsc-drift.c プロジェクト: terminus/c-hacks
/*
 * The idea behind this state machine is taken from Linux's
 * lockless stop-machine code.
 */
void *state_machine(void *args) {
	struct rusage u, v;
	int tid = (int)((unsigned long)args);
	unsigned long assemble, stamp_counter, stamp_counter_mp;
	int master = 0, slave;

	__e_m(tid > (spawn - 1), "How'd this happen?");

	if (tid == 0)
		master = 1;

	slave = !master;

	/* We want to see how badly we ended up spinning,
	 * waiting for threads on other CPUs to catch up.
	 *
	 * We'll use these variables as very unscientific
	 * counters.
	 */
	assemble = stamp_counter = stamp_counter_mp = 0;

	if (slave) {
		while (atomic_read(&command) != SETUP);
	}

	if (master) {
		atomic_set(&assembled, 0);
		atomic_set(&command, SETUP);
	}

	/*
	 * We are screwed if this fails: there will be gaps
	 * in ids. And the _mp version will hang forever.
	 */
	thread_bind(tid);

	/* Remember the page-faults and such. */
	__w(
	getrusage(RUSAGE_THREAD, &u) != 0,
	   	"(errno=%d)", errno);

	/* Done with setup. */
	atomic_inc(&assembled);

	/* wait for master to tell us to assemble */
	if (slave) {
		while (atomic_read(&command) != BEFORE_STAMP)
			assemble++;
	}

	/* give assemble command */
	if (master) {
		/* We want to kick-off all the slaves at
		 * the same time. Wait for them to assemble. */
		while (atomic_read(&assembled) != spawn);

		atomic_set(&assembled, 0);
		atomic_set(&command, BEFORE_STAMP);
	}

	/* assemble work */
	atomic_inc(&assembled);

	/* Everybody is at BEFORE_STAMP, raring to STAMP */

	/* give stamp command */
	if (master) {
		/* wait for slaves */
		while (atomic_read(&assembled) != spawn)
			assemble++;
		atomic_set(&assembled, 0);
		atomic_set(&command, STAMP_COUNTER);
	}

	/* wait for stamp command */
	if (slave) {
		while (atomic_read(&command) != STAMP_COUNTER)
			stamp_counter++;
	}

	/* stamp work */
	rdtscll(counter[tid].ts);
	atomic_inc(&assembled);

	/* give stamp_mp command */
	if (master) {
		/* wait for slaves */
		while (atomic_read(&assembled) != spawn)
			stamp_counter++;

		atomic_set(&assembled, 0);
		atomic_set(&command, STAMP_COUNTER_MP);
	}

	/* wait for stamp command */
	if (slave) {
		while (atomic_read(&command) != STAMP_COUNTER_MP)
			stamp_counter_mp++;
	}

	/*
	 * Do the work.
	 */
	while (atomic_read(&assembled) != tid);
	rdtscll(counter_mp[tid].ts);
	atomic_inc(&assembled);

	if (master) {
		while (atomic_read(&assembled) != spawn);
	}

	__w(
		getrusage(RUSAGE_THREAD, &v) != 0,
	   	"(errno=%d)", errno);
	
	rundata[tid].u = u;
	rundata[tid].v = v;
	rundata[tid].assemble = assemble;

	rundata[tid].stamp_counter = stamp_counter;
	rundata[tid].stamp_counter_mp = stamp_counter_mp;

	return NULL;
}
コード例 #16
0
ファイル: startup.c プロジェクト: nathanielg69/xnu
/*
 * Now running in a thread.  Kick off other services,
 * invoke user bootstrap, enter pageout loop.
 */
static void
kernel_bootstrap_thread(void)
{
    processor_t		processor = current_processor();

#define kernel_bootstrap_thread_kprintf(x...) /* kprintf("kernel_bootstrap_thread: " x) */
    kernel_bootstrap_thread_kprintf("calling idle_thread_create\n");
    /*
     * Create the idle processor thread.
     */
    idle_thread_create(processor);

    /*
     * N.B. Do not stick anything else
     * before this point.
     *
     * Start up the scheduler services.
     */
    kernel_bootstrap_thread_kprintf("calling sched_startup\n");
    sched_startup();

    /*
     * Thread lifecycle maintenance (teardown, stack allocation)
     */
    kernel_bootstrap_thread_kprintf("calling thread_daemon_init\n");
    thread_daemon_init();

    /*
     * Thread callout service.
     */
    kernel_bootstrap_thread_kprintf("calling thread_call_initialize\n");
    thread_call_initialize();

    /*
     * Remain on current processor as
     * additional processors come online.
     */
    kernel_bootstrap_thread_kprintf("calling thread_bind\n");
    thread_bind(processor);

    /*
     * Kick off memory mapping adjustments.
     */
    kernel_bootstrap_thread_kprintf("calling mapping_adjust\n");
    mapping_adjust();

    /*
     *	Create the clock service.
     */
    kernel_bootstrap_thread_kprintf("calling clock_service_create\n");
    clock_service_create();

    /*
     *	Create the device service.
     */
    device_service_create();

    kth_started = 1;

#if (defined(__i386__) || defined(__x86_64__)) && NCOPY_WINDOWS > 0
    /*
     * Create and initialize the physical copy window for processor 0
     * This is required before starting kicking off  IOKit.
     */
    cpu_physwindow_init(0);
#endif

    vm_kernel_reserved_entry_init();

#if MACH_KDP
    kernel_bootstrap_kprintf("calling kdp_init\n");
    kdp_init();
#endif

#if CONFIG_COUNTERS
    pmc_bootstrap();
#endif

#if (defined(__i386__) || defined(__x86_64__))
    if (turn_on_log_leaks && !new_nkdbufs)
        new_nkdbufs = 200000;
    start_kern_tracing(new_nkdbufs);
    if (turn_on_log_leaks)
        log_leaks = 1;
#endif

#ifdef	IOKIT
    PE_init_iokit();
#endif

    (void) spllo();		/* Allow interruptions */

#if (defined(__i386__) || defined(__x86_64__)) && NCOPY_WINDOWS > 0
    /*
     * Create and initialize the copy window for processor 0
     * This also allocates window space for all other processors.
     * However, this is dependent on the number of processors - so this call
     * must be after IOKit has been started because IOKit performs processor
     * discovery.
     */
    cpu_userwindow_init(0);
#endif

#if (!defined(__i386__) && !defined(__x86_64__))
    if (turn_on_log_leaks && !new_nkdbufs)
        new_nkdbufs = 200000;
    start_kern_tracing(new_nkdbufs);
    if (turn_on_log_leaks)
        log_leaks = 1;
#endif

    /*
     *	Initialize the shared region module.
     */
    vm_shared_region_init();
    vm_commpage_init();
    vm_commpage_text_init();

#if CONFIG_MACF
    mac_policy_initmach();
#endif

    /*
     * Initialize the global used for permuting kernel
     * addresses that may be exported to userland as tokens
     * using VM_KERNEL_ADDRPERM(). Force the random number
     * to be odd to avoid mapping a non-zero
     * word-aligned address to zero via addition.
     */
    vm_kernel_addrperm = (vm_offset_t)early_random() | 1;

    /*
     *	Start the user bootstrap.
     */
#ifdef	MACH_BSD
    bsd_init();
#endif

    /*
     * Get rid of segments used to bootstrap kext loading. This removes
     * the KLD, PRELINK symtab, LINKEDIT, and symtab segments/load commands.
     */
#if 0
    OSKextRemoveKextBootstrap();
#endif

    serial_keyboard_init();		/* Start serial keyboard if wanted */

    vm_page_init_local_q();

    thread_bind(PROCESSOR_NULL);

    /*
     *	Become the pageout daemon.
     */
    vm_pageout();
    /*NOTREACHED*/
}
コード例 #17
0
ファイル: main.c プロジェクト: pigirons/spmv
int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        fprintf(stderr, "usage: %s csr_matrix_file\n", argv[0]);
        exit(0);
    }

    int i, j, k;

    struct timespec start, end;

    int num_threads = 1;
#pragma omp parallel
    {
#pragma omp master
        {
            num_threads = omp_get_num_threads();
        }
    }
    printf("Thread number: %d.\n", num_threads);

#pragma omp parallel for
    for (i = 0; i < num_threads; i++)
    {
        int cpu = omp_get_thread_num();
        thread_bind(cpu);
    }

    FILE *fp;

    struct csr_mat_t csr, csr_re, csr_t, csr_t_re, csr_t_t;
    struct blk_mat_t blk;

    struct csr_cont_t csr_h, csr_v;
    struct blk_cont_t blk_h, blk_t_h;

    read_csr_mat(argv[1], &csr);
    int rows = csr.rows;
    int cols = csr.cols;
    INT64 non_zeros = csr.non_zeros;

    csr_transpose(&csr, &csr_t);
    release_csr_mat(&csr);
    int *reorder_map = (int*)malloc(cols * sizeof(int));
    csr_reorder(&csr_t, &csr_re, reorder_map);
    release_csr_mat(&csr_t);
    csr_transpose(&csr_re, &csr_t_t);
    release_csr_mat(&csr_re);
    split_csr_lb_nz(&csr_t_t, &csr_h, num_threads, SPLIT_HORIZON);
    release_csr_mat(&csr_t_t);
    csr_cont_to_blk_cont(&csr_h, &blk_h);
    release_csr_cont(&csr_h);

    printf("Notify: finished the preprocessing.\n");

    FLOAT *x = (FLOAT*)numa_alloc(cols * sizeof(FLOAT));
    FLOAT *y = (FLOAT*)numa_alloc(rows * sizeof(FLOAT));

    for (i = 0; i < cols; i++)
    {
        x[i] = 1.0;
    }

    // warm up
    spmv_blks(&blk_h, x, y, NULL);

    printf("Notify: begin csr spmv.\n");
    clock_gettime(CLOCK_MONOTONIC_RAW, &start);
    for (i = 0; i < LOOP_TIME; i++)
    {
        spmv_blks(&blk_h, x, y, NULL);
    }
    clock_gettime(CLOCK_MONOTONIC_RAW, &end);
    double time = get_sec(&start, &end) / LOOP_TIME;
    double gflops = 2.0 * non_zeros / time * 1e-9;
    printf("Notify: blk spmv time = %lfs, perf = %lf GFLOPS.\n", time, gflops);
    // result_file(y, rows);

    return 0;
}
コード例 #18
0
ファイル: chud_thread.c プロジェクト: OpenDarwin-CVS/SEDarwin
__private_extern__
kern_return_t chudxnu_unbind_current_thread(void)
{
    thread_bind(current_thread(), PROCESSOR_NULL);
    return KERN_SUCCESS;
}
コード例 #19
0
ファイル: main.c プロジェクト: pigirons/sgemm_hsw
void test_kernel()
{
    int i;

    struct timespec start, end;
    double t, gflops;

    thread_bind(0);

    float *a = (float*)page_alloc(48 * 48 * sizeof(float));
    float *b = (float*)page_alloc(48 * 48 * sizeof(float));
    float *cn = (float*)page_alloc(48 * 48 * sizeof(float));
    float *ca = (float*)page_alloc(48 * 48 * sizeof(float));
    float *cf = (float*)page_alloc(48 * 48 * sizeof(float));

    srand(time(NULL));

    for (i = 0; i < 48 * 48; i++)
    {
        a[i] = (float)rand() / RAND_MAX;
        b[i] = (float)rand() / RAND_MAX;
    }
    memset(cn, 0, 48 * 48 * sizeof(float));
    memset(ca, 0, 48 * 48 * sizeof(float));
    memset(cf, 0, 48 * 48 * sizeof(float));

    // check error
    sgemm_naive_48_48_48(a, b, cn);
    sgemm_kernel_avx_48_48_48(a, b, ca);
    sgemm_kernel_fma_48_48_48(a, b, cf);

    printf("AVX-tuned version check result:\n");
    verify(cn, ca);
    printf("FMA-tuned version check result:\n");
    verify(cn, cf);

    // naive version
    // warm up
    for (i = 0; i < NAIVE_LOOP_TIME; i++)
    {
        sgemm_naive_48_48_48(a, b, cn);
    }
    clock_gettime(CLOCK_MONOTONIC_RAW, &start);
    for (i = 0; i < NAIVE_LOOP_TIME; i++)
    {
        sgemm_naive_48_48_48(a, b, cn);
    }
    clock_gettime(CLOCK_MONOTONIC_RAW, &end);

    t = get_time(&start, &end);
    gflops = 2.0 * NAIVE_LOOP_TIME * 48 * 48 * 48 / t * 1e-9;

    printf("Naive version: time = %lfs, perf = %lf GFLOPS.\n", t, gflops);

    // avx-tuned version
    // warm up
    for (i = 0; i < LOOP_TIME; i++)
    {
        sgemm_kernel_avx_48_48_48(a, b, ca);
    }
    clock_gettime(CLOCK_MONOTONIC_RAW, &start);
    for (i = 0; i < LOOP_TIME; i++)
    {
        sgemm_kernel_avx_48_48_48(a, b, ca);
    }
    clock_gettime(CLOCK_MONOTONIC_RAW, &end);

    t = get_time(&start, &end);
    gflops = 2.0 * LOOP_TIME * 48 * 48 * 48 / t * 1e-9;

    printf("AVX-tuned version: time = %lfs, perf = %lf GFLOPS.\n", t, gflops);

    // fma-tuned version
    // warm up
    for (i = 0; i < LOOP_TIME; i++)
    {
        sgemm_kernel_fma_48_48_48(a, b, cf);
    }
    clock_gettime(CLOCK_MONOTONIC_RAW, &start);
    for (i = 0; i < LOOP_TIME; i++)
    {
        sgemm_kernel_fma_48_48_48(a, b, cf);
    }
    clock_gettime(CLOCK_MONOTONIC_RAW, &end);

    t = get_time(&start, &end);
    gflops = 2.0 * LOOP_TIME * 48 * 48 * 48 / t * 1e-9;

    printf("FMA-tuned version: time = %lfs, perf = %lf GFLOPS.\n", t, gflops);

    page_free(a, 48 * 48 * sizeof(float));
    page_free(b, 48 * 48 * sizeof(float));
    page_free(cn, 48 * 48 * sizeof(float));
    page_free(ca, 48 * 48 * sizeof(float));
    page_free(cf, 48 * 48 * sizeof(float));
}
コード例 #20
0
ファイル: startup.c プロジェクト: openmach/openmach
/*
 * Now running in a thread.  Create the rest of the kernel threads
 * and the bootstrap task.
 */
void start_kernel_threads()
{
	register int	i;

	/*
	 *	Create the idle threads and the other
	 *	service threads.
	 */
	for (i = 0; i < NCPUS; i++) {
	    if (machine_slot[i].is_cpu) {
		thread_t	th;

		(void) thread_create(kernel_task, &th);
		thread_bind(th, cpu_to_processor(i));
		thread_start(th, idle_thread);
		thread_doswapin(th);
		(void) thread_resume(th);
	    }
	}

	(void) kernel_thread(kernel_task, reaper_thread, (char *) 0);
	(void) kernel_thread(kernel_task, swapin_thread, (char *) 0);
	(void) kernel_thread(kernel_task, sched_thread, (char *) 0);

#if	NCPUS > 1
	/*
	 *	Create the shutdown thread.
	 */
	(void) kernel_thread(kernel_task, action_thread, (char *) 0);

	/*
	 *	Allow other CPUs to run.
	 */
	start_other_cpus();
#endif	NCPUS > 1

	/*
	 *	Create the device service.
	 */
	device_service_create();

	/*
	 *	Initialize NORMA ipc system.
	 */
#if	NORMA_IPC
	norma_ipc_init();
#endif	NORMA_IPC

	/*
	 *	Initialize NORMA vm system.
	 */
#if	NORMA_VM
	norma_vm_init();
#endif	NORMA_VM

	/*
	 *	Start the user bootstrap.
	 */
	bootstrap_create();

#if	XPR_DEBUG
	xprinit();		/* XXX */
#endif	XPR_DEBUG

	/*
	 *	Become the pageout daemon.
	 */
	(void) spl0();
	vm_pageout();
	/*NOTREACHED*/
}