コード例 #1
0
ファイル: main.c プロジェクト: lieb005/liebscher_pic
interrupt void ISR()
{
	if (TMR1IE && TMR1IF)
	{
		TMR1IF = OFF;
		TMR1ON = OFF;
		if (++count == MAX_COUNT)
		{
			TMR1 = 0xFFFF - EXTRA_COUNT;
			TMR1ON = ON;
			idle_loop();
		}
		else if (++count > MAX_COUNT)
		{
			stop();
			reset();
			blink();
		}
		else if (++count < MAX_COUNT)
		{
			TMR1 = 0;
			TMR1ON = ON;
			idle_loop();

		}
	}
	if (INTF && INTE)
	{
		INTF = 0;
		// if timer is running, we are not blinking
		if (TMR1ON)
		{
#if DEBUG == 1
			LED = ~LED;
#endif
			idle_loop();
		}
		else
		{
			// reset timer and start it because it was blinking
			start();
#if DEBUG == 1
			LED = 1;
			int tmp = 0;
			while (++tmp < 500);
#endif
			idle_loop();
		}
	}
}
コード例 #2
0
ファイル: ezchronos.c プロジェクト: lieb005/My_Stuff
// *************************************************************************************************
// @fn          main
// @brief       Main routine
// @param       none
// @return      none
// *************************************************************************************************
int main(void)
{
#ifdef EMU
	emu_init();
#endif
	// Init MCU 
	init_application();

	// Assign initial value to global variables
	init_global_variables();

#ifdef CONFIG_TEST
	// Branch to welcome screen
	test_mode();
#else
	display_all_off();
#endif
	
	// Main control loop: wait in low power mode until some event needs to be processed
	while(1)
	{
		// When idle go to LPM3
    	idle_loop();

    	// Process wake-up events
    	if (button.all_flags || sys.all_flags) wakeup_event();
    	
    	// Process actions requested by logic modules
    	if (request.all_flags) process_requests();
    	
    	// Before going to LPM3, update display
    	if (display.all_flags) display_update();	
 	}	
}
コード例 #3
0
ファイル: gc.c プロジェクト: alvstakahashi/MRUBY2C-SRC
static size_t
incremental_gc(mrb_state *mrb, size_t limit)
{
  idle_loop();
  switch (mrb->gc_state) {
  case GC_STATE_ROOT:
    root_scan_phase(mrb);
    mrb->gc_state = GC_STATE_MARK;
    flip_white_part(mrb);
    return 0;
  case GC_STATE_MARK:
    if (mrb->gray_list) {
      return incremental_marking_phase(mrb, limit);
    }
    else {
      final_marking_phase(mrb);
      prepare_incremental_sweep(mrb);
      return 0;
    }
  case GC_STATE_SWEEP: {
     size_t tried_sweep = 0;
     tried_sweep = incremental_sweep_phase(mrb, limit);
     if (tried_sweep == 0)
       mrb->gc_state = GC_STATE_ROOT;
     return tried_sweep;
  }
  default:
    /* unknown state */
    mrb_assert(0);
    return 0;
  }
}
コード例 #4
0
ファイル: main.c プロジェクト: lieb005/liebscher_pic
void config()
{
	// disable POR and BOR flags (inverted)
	nPOR = 1;
	nBOR = 1;
	nBOD = 1;
	// disable analog ins
	ANSEL = 0;

	// assign prescaler to WDT (instead of timer0)
	PSA = 1;
	// turn off gate enable
	TMR1GE = OFF;

	// //enable Synchronous mode
	//T1SYNC = 1;

	// prescale clock by 8
	T1CKPS1 = 1;
	T1CKPS0 = 1;
	// use internal clock/4 for incrementing
	TMR1CS = 0;
	// clear timer 1
	TMR1 = 0;

	// set 2 to input and 1 to out
	TRISIO2 = 1;
	TRISIO1 = 0;

#if DEBUG == 3
	LED = 1;
	idle_loop();
#endif

	// enable weak pullups
	nGPPU = ~ON;
	WPU = ~0x8;
	// enable interrupts
	//global
	GIE = ON;
	// peripheral
	PEIE = ON;
	// Timer 1 clear
	TMR1IF = OFF;
	// timer1 enable
	TMR1IE = ON;
	// clear interrupt before enabling
	INTF = OFF;
	// enable interrupt on change for INT2
	INTE = ON;
	// set to falling edge of interrupt
	INTEDG = 0;

	return;
}
コード例 #5
0
ファイル: smp.c プロジェクト: zwegner/zct
/**
thread_init():
Initialize a thread on Windows. This is written by Teemu Pudas.
Created 071108; last modified 071108
**/
DWORD WINAPI thread_init(LPVOID arg)
{
	board.id = *(int *)arg;
	initialize_board(NULL);
	initialize_hash();
	board.split_ply = board.split_ply_stack;
	board.split_ply_stack[0] = -1;
	board.split_point = board.split_point_stack;
	board.split_point_stack[0] = NULL;
	idle_loop(board.id);
	return 0;
}
コード例 #6
0
ファイル: main.c プロジェクト: lieb005/liebscher_pic
int main(int argc, char** argv)
{
#if DEBUG == 4
	TRISIO2 = 1;
	TRISIO1 = 0;
	nGPPU = 0;
	LED = 1;
	while (1)
	{
	}
#elif DEBUG == 0
	//asm("nop");
	//while(1);
	config();
	start();
	// keeps the program going
	idle_loop();
#endif
	return (EXIT_SUCCESS);
}
コード例 #7
0
ファイル: idle.c プロジェクト: BackupTheBerlios/tuxap
int cpu_idle(void)
{
	idle_loop();
	return 0;
}
コード例 #8
0
ファイル: posix_timers.c プロジェクト: 020gzh/linux
static int check_itimer(int which)
{
	int err;
	struct timeval start, end;
	struct itimerval val = {
		.it_value.tv_sec = DELAY,
	};

	printf("Check itimer ");

	if (which == ITIMER_VIRTUAL)
		printf("virtual... ");
	else if (which == ITIMER_PROF)
		printf("prof... ");
	else if (which == ITIMER_REAL)
		printf("real... ");

	fflush(stdout);

	done = 0;

	if (which == ITIMER_VIRTUAL)
		signal(SIGVTALRM, sig_handler);
	else if (which == ITIMER_PROF)
		signal(SIGPROF, sig_handler);
	else if (which == ITIMER_REAL)
		signal(SIGALRM, sig_handler);

	err = gettimeofday(&start, NULL);
	if (err < 0) {
		perror("Can't call gettimeofday()\n");
		return -1;
	}

	err = setitimer(which, &val, NULL);
	if (err < 0) {
		perror("Can't set timer\n");
		return -1;
	}

	if (which == ITIMER_VIRTUAL)
		user_loop();
	else if (which == ITIMER_PROF)
		kernel_loop();
	else if (which == ITIMER_REAL)
		idle_loop();

	gettimeofday(&end, NULL);
	if (err < 0) {
		perror("Can't call gettimeofday()\n");
		return -1;
	}

	if (!check_diff(start, end))
		printf("[OK]\n");
	else
		printf("[FAIL]\n");

	return 0;
}

static int check_timer_create(int which)
{
	int err;
	timer_t id;
	struct timeval start, end;
	struct itimerspec val = {
		.it_value.tv_sec = DELAY,
	};

	printf("Check timer_create() ");
	if (which == CLOCK_THREAD_CPUTIME_ID) {
		printf("per thread... ");
	} else if (which == CLOCK_PROCESS_CPUTIME_ID) {
		printf("per process... ");
	}
	fflush(stdout);

	done = 0;
	err = timer_create(which, NULL, &id);
	if (err < 0) {
		perror("Can't create timer\n");
		return -1;
	}
	signal(SIGALRM, sig_handler);

	err = gettimeofday(&start, NULL);
	if (err < 0) {
		perror("Can't call gettimeofday()\n");
		return -1;
	}

	err = timer_settime(id, 0, &val, NULL);
	if (err < 0) {
		perror("Can't set timer\n");
		return -1;
	}

	user_loop();

	gettimeofday(&end, NULL);
	if (err < 0) {
		perror("Can't call gettimeofday()\n");
		return -1;
	}

	if (!check_diff(start, end))
		printf("[OK]\n");
	else
		printf("[FAIL]\n");

	return 0;
}

int main(int argc, char **argv)
{
	printf("Testing posix timers. False negative may happen on CPU execution \n");
	printf("based timers if other threads run on the CPU...\n");

	if (check_itimer(ITIMER_VIRTUAL) < 0)
		return ksft_exit_fail();

	if (check_itimer(ITIMER_PROF) < 0)
		return ksft_exit_fail();

	if (check_itimer(ITIMER_REAL) < 0)
		return ksft_exit_fail();

	if (check_timer_create(CLOCK_THREAD_CPUTIME_ID) < 0)
		return ksft_exit_fail();

	/*
	 * It's unfortunately hard to reliably test a timer expiration
	 * on parallel multithread cputime. We could arm it to expire
	 * on DELAY * nr_threads, with nr_threads busy looping, then wait
	 * the normal DELAY since the time is elapsing nr_threads faster.
	 * But for that we need to ensure we have real physical free CPUs
	 * to ensure true parallelism. So test only one thread until we
	 * find a better solution.
	 */
	if (check_timer_create(CLOCK_PROCESS_CPUTIME_ID) < 0)
		return ksft_exit_fail();

	return ksft_exit_pass();
}
コード例 #9
0
ファイル: user.c プロジェクト: romelemperado/psx
// *************************************************************************************************
// @fn          set_value
// @brief       Generic value setting routine
// @param       s32 * value						Pointer to value to set
//				u8digits						Number of digits
//				u8 blanks						Number of whitespaces before first valid digit
//				s32 limitLow					Lower limit of value
//				s32 limitHigh					Upper limit of value
//				u16 mode		
//				u8 segments					Segments where value should be drawn
//				fptr_setValue_display_function1		Value-specific display routine
// @return      none
// *************************************************************************************************
void set_value(s32 * value, u8 digits, u8 blanks, s32 limitLow, s32 limitHigh, u16 mode, u8 segments, void (*fptr_setValue_display_function1)(u8 segments, u32 value, u8 digits, u8 blanks))
{
	u8 update;
	s16 stepValue = 1;
	u8 doRound = 0;
	u32 val;
	
	// Clear button flags
	button.all_flags = 0;
	
	// Clear blink memory
	clear_blink_mem();
	
	// For safety only - buzzer on/off and button_repeat share same IRQ
	stop_buzzer();
	
	// Init step size and repeat counter
	sButton.repeats = 0;
	
	// Initial display update
	update = 1;
	
	// Turn on 200ms button repeat function 
	button_repeat_on(200);
	
	// Start blinking with with 2Hz
	set_blink_rate(BIT6 + BIT5);
	
	// Value set loop
	while(1) 
	{
		// Idle timeout: exit function
		if (sys.flag.idle_timeout) break;

		// STAR (short) button: exit function
		if (button.flag.star) break;

		// NUM button: exit function and goto to next value (if available)
		if (button.flag.num)
		{
			if ((mode & SETVALUE_NEXT_VALUE) == SETVALUE_NEXT_VALUE) break;
		}

		// UP button: increase value
		if(button.flag.up)
		{
			// Increase value
			* value = * value + stepValue;
			
			// Check value limits
			if (* value > limitHigh) 
			{
				// Check if value can roll over, else stick to limit
				if ((mode & SETVALUE_ROLLOVER_VALUE) == SETVALUE_ROLLOVER_VALUE) 	* value = limitLow;
				else 																* value = limitHigh;				
					
				// Reset step size to default
				stepValue = 1;	
			}

			// Trigger display update
			update = 1;
			
			// Clear button flag
			button.flag.up = 0;
		}
		
		// DOWN button: decrease value
		if(button.flag.down)
		{
			// Decrease value
			* value = * value - stepValue;
			
			// Check value limits
			if (* value < limitLow) 
			{
				// Check if value can roll over, else stick to limit
				if ((mode & SETVALUE_ROLLOVER_VALUE) == SETVALUE_ROLLOVER_VALUE)	* value = limitHigh;
				else																* value = limitLow;
					
				// Reset step size to default
				stepValue = 1;	
			}

			// Trigger display update
			update = 1;

			// Clear button flag	
			button.flag.down = 0;
		}

		
		// When fast mode is enabled, increase step size if Sx button is continuously
		if ((mode & SETVALUE_FAST_MODE) == SETVALUE_FAST_MODE)
		{
			switch (sButton.repeats)
			{
				case 0:			stepValue = 1;		doRound = 0; 	break;
				case 10:		
				case -10:		stepValue = 10;		doRound = 1; 	break;
				case 20:			
				case -20:		stepValue = 100;	doRound = 1; 	break;
				case 30:			
				case -30:		stepValue = 1000;	doRound = 1; 	break;
			}
			
			// Round value to avoid odd numbers on display
			if (stepValue != 1 && doRound == 1)	
			{
				* value -= * value % stepValue;
				doRound = 0;
			}
		}

		// Update display when there is new data
		if (update)
		{
			// Display up or down arrow according to sign of value
			if ((mode & SETVALUE_DISPLAY_ARROWS) == SETVALUE_DISPLAY_ARROWS)
			{
				if (* value >= 0)
				{
					display_symbol(LCD_SYMB_ARROW_UP, SEG_ON);
					display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
					val = *value;
				}
				else 
				{
					display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
					display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON);
					val = *value * (-1);
				}
			}
			else
			{
				val = *value;
			}

			// Display function can either display value directly, modify value before displaying 
			// or display a string referenced by the value
			fptr_setValue_display_function1(segments, val, digits, blanks);

			// Clear update flag
			update = 0;
		}
		
		// Call idle loop to serve background tasks
		idle_loop();
		
	}
	
	// Clear up and down arrows
	display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
	display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
	
	// Set blinking rate to 1Hz and stop
	set_blink_rate(BIT7 + BIT6 + BIT5);
	clear_blink_mem();
	
	// Turn off button repeat function
	button_repeat_off();
}
コード例 #10
0
ファイル: cpu_subr.c プロジェクト: ryo/netbsd-src
void
cpu_hatch(struct cpu_info *ci)
{
	struct pmap_tlb_info * const ti = ci->ci_tlb_info;

	/*
	 * Invalidate all the TLB enties (even wired ones) and then reserve
	 * space for the wired TLB entries.
	 */
	mips3_cp0_wired_write(0);
	tlb_invalidate_all();
	mips3_cp0_wired_write(ti->ti_wired);

	/*
	 * Setup HWRENA and USERLOCAL COP0 registers (MIPSxxR2).
	 */
	cpu_hwrena_setup();

	/*
	 * If we are using register zero relative addressing to access cpu_info
	 * in the exception vectors, enter that mapping into TLB now.
	 */
	if (ci->ci_tlb_slot >= 0) {
		const uint32_t tlb_lo = MIPS3_PG_G|MIPS3_PG_V
		    | mips3_paddr_to_tlbpfn((vaddr_t)ci);
		const struct tlbmask tlbmask = {
			.tlb_hi = -PAGE_SIZE | KERNEL_PID,
#if (PGSHIFT & 1)
			.tlb_lo0 = tlb_lo,
			.tlb_lo1 = tlb_lo + MIPS3_PG_NEXT,
#else
			.tlb_lo0 = 0,
			.tlb_lo1 = tlb_lo,
#endif
			.tlb_mask = -1,
		};

		tlb_invalidate_addr(tlbmask.tlb_hi, KERNEL_PID);
		tlb_write_entry(ci->ci_tlb_slot, &tlbmask);
	}

	/*
	 * Flush the icache just be sure.
	 */
	mips_icache_sync_all();

	/*
	 * Let this CPU do its own initialization (for things that have to be
	 * done on the local CPU).
	 */
	(*mips_locoresw.lsw_cpu_init)(ci);

	// Show this CPU as present.
	atomic_or_ulong(&ci->ci_flags, CPUF_PRESENT);

	/*
	 * Announce we are hatched
	 */
	kcpuset_atomic_set(cpus_hatched, cpu_index(ci));

	/*
	 * Now wait to be set free!
	 */
	while (! kcpuset_isset(cpus_running, cpu_index(ci))) {
		/* spin, spin, spin */
	}

	/*
	 * initialize the MIPS count/compare clock
	 */
	mips3_cp0_count_write(ci->ci_data.cpu_cc_skew);
	KASSERT(ci->ci_cycles_per_hz != 0);
	ci->ci_next_cp0_clk_intr = ci->ci_data.cpu_cc_skew + ci->ci_cycles_per_hz;
	mips3_cp0_compare_write(ci->ci_next_cp0_clk_intr);
	ci->ci_data.cpu_cc_skew = 0;

	/*
	 * Let this CPU do its own post-running initialization
	 * (for things that have to be done on the local CPU).
	 */
	(*mips_locoresw.lsw_cpu_run)(ci);

	/*
	 * Now turn on interrupts (and verify they are on).
	 */
	spl0();
	KASSERTMSG(ci->ci_cpl == IPL_NONE, "cpl %d", ci->ci_cpl);
	KASSERT(mips_cp0_status_read() & MIPS_SR_INT_IE);

	kcpuset_atomic_set(pmap_kernel()->pm_onproc, cpu_index(ci));
	kcpuset_atomic_set(pmap_kernel()->pm_active, cpu_index(ci));

	/*
	 * And do a tail call to idle_loop
	 */
	idle_loop(NULL);
}

void
cpu_boot_secondary_processors(void)
{
	CPU_INFO_ITERATOR cii;
	struct cpu_info *ci;
	for (CPU_INFO_FOREACH(cii, ci)) {
		if (CPU_IS_PRIMARY(ci))
			continue;
		KASSERT(ci->ci_data.cpu_idlelwp);

		/*
		 * Skip this CPU if it didn't sucessfully hatch.
		 */
		if (!kcpuset_isset(cpus_hatched, cpu_index(ci)))
			continue;

		ci->ci_data.cpu_cc_skew = mips3_cp0_count_read();
		atomic_or_ulong(&ci->ci_flags, CPUF_RUNNING);
		kcpuset_set(cpus_running, cpu_index(ci));
		// Spin until the cpu calls idle_loop
		for (u_int i = 0; i < 100; i++) {
			if (kcpuset_isset(cpus_running, cpu_index(ci)))
				break;
			delay(1000);
		}
	}
}
コード例 #11
0
void
cpu_hatch(struct cpu_info *ci)
{
	struct pmap_tlb_info * const ti = ci->ci_tlb_info;

	/*
	 * Invalidate all the TLB enties (even wired ones) and then reserve
	 * space for the wired TLB entries.
	 */
	mips3_cp0_wired_write(0);
	tlb_invalidate_all();
	mips3_cp0_wired_write(ti->ti_wired);

	/*
	 * Setup HWRENA and USERLOCAL COP0 registers (MIPSxxR2).
	 */
	cpu_hwrena_setup();

	/*
	 * If we are using register zero relative addressing to access cpu_info
	 * in the exception vectors, enter that mapping into TLB now.
	 */
	if (ci->ci_tlb_slot >= 0) {
		const uint32_t tlb_lo = MIPS3_PG_G|MIPS3_PG_V
		    | mips3_paddr_to_tlbpfn((vaddr_t)ci);

		tlb_enter(ci->ci_tlb_slot, -PAGE_SIZE, tlb_lo);
	}

	/*
	 * Flush the icache just be sure.
	 */
	mips_icache_sync_all();

	/*
	 * Let this CPU do its own initialization (for things that have to be
	 * done on the local CPU).
	 */
	(*mips_locoresw.lsw_cpu_init)(ci);

	/*
	 * Announce we are hatched
	 */
	CPUSET_ADD(cpus_hatched, cpu_index(ci));

	/*
	 * Now wait to be set free!
	 */
	while (! CPUSET_HAS_P(cpus_running, cpu_index(ci))) {
		/* spin, spin, spin */
	}

	/*
	 * initialize the MIPS count/compare clock
	 */
	mips3_cp0_count_write(ci->ci_data.cpu_cc_skew);
	KASSERT(ci->ci_cycles_per_hz != 0);
	ci->ci_next_cp0_clk_intr = ci->ci_data.cpu_cc_skew + ci->ci_cycles_per_hz;
	mips3_cp0_compare_write(ci->ci_next_cp0_clk_intr);
	ci->ci_data.cpu_cc_skew = 0;

	/*
	 * Let this CPU do its own post-running initialization
	 * (for things that have to be done on the local CPU).
	 */
	(*mips_locoresw.lsw_cpu_run)(ci);

	/*
	 * Now turn on interrupts.
	 */
	spl0();

	/*
	 * And do a tail call to idle_loop
	 */
	idle_loop(NULL);
}
コード例 #12
0
ファイル: smp.c プロジェクト: zwegner/zct
/**
initialize_smp():
Initializes the smp functionality for the given number of processes.
Created 081305; last modified 103008
**/
void initialize_smp(int procs)
{
	int x;
	int y;
	int z;

	/* Set up the default signals. This is because the child processes
		inherit all of the parent's signal handlers, and we don't want that. */
	signal(SIGINT, SIG_DFL);
	signal(SIGTERM, SIG_DFL);
//	signal(SIGCHLD, SIG_IGN);

	if (smp_data != NULL)
		smp_cleanup();
	else if (atexit(smp_cleanup) == -1 || atexit(smp_cleanup_final) == -1)
	{
		smp_cleanup();
		smp_cleanup_final();
		fatal_error("fatal error: atexit failed");
	}
	zct->process_count = procs;

	/* Allocate the shared memory to the various data structures needed. */
	split_point_size = sizeof(SPLIT_POINT) * MAX_SPLIT_POINTS;
	smp_block_size = sizeof(SMP_BLOCK) * procs;
	smp_data_size = sizeof(SMP_DATA);
	split_point = (SPLIT_POINT *)shared_alloc(split_point_size);
	smp_block = (SMP_BLOCK *)shared_alloc(smp_block_size);
	smp_data = (SMP_DATA *)shared_alloc(smp_data_size);
	
#define DBG(t,s,i) do{int p;\
		print("%s: %x\n", #t, sizeof(t));\
		for (p=0;p<i;p++){\
			print("%p",&s[p]);\
			if(p>0)\
				print(" %i",((BITBOARD)&s[p])-((BITBOARD)&s[p-1]));\
				print("\n");\
		}}while(0)

	/*
	DBG(SMP_BLOCK, smp_block, procs);
	DBG(SMP_DATA, smp_data, 1);
*/
	/* Initialize the data. */
	/* SMP data */
	smp_data->return_flag = FALSE;
	/* smp blocks */
	for (x = 0; x < procs; x++)
	{
		smp_block[x].id = x;
		smp_block[x].idle = FALSE;
		smp_block[x].last_idle_time = 0;
		smp_block[x].message_count = 0;
		smp_block[x].input = 0;
		smp_block[x].output = 0;
		
		for (y = 0; y < MAX_PLY; y++)
			initialize_split_score(&smp_block[x].tree.sb_score[y]);
//		initialize_split_score(&smp_block[x].tree.split_score);

		/* The split ID is id*MAX_CPUS+board.id, so instead of calculating
			that every time we split, we just start at board.id and increment
			by MAX_CPUS. */
		smp_block[x].split_id = x;

#ifdef ZCT_WINDOWS
		_pipe(smp_block[x].wait_pipe, 8, O_BINARY);
#else
		pipe(smp_block[x].wait_pipe);
#endif
	}

	/* split points */
	for (x = 0; x < MAX_SPLIT_POINTS; x++)
	{
		split_point[x].n = x;
		split_point[x].active = FALSE;
		split_point[x].child_count = 0;
		for (y = 0; y < MAX_CPUS; y++)
		{
			split_point[x].update[y] = FALSE;
			split_point[x].is_child[y] = FALSE;
		}
	}

	/* main processor's smp info */
	board.id = 0;
	board.split_ply = board.split_ply_stack;
	board.split_ply_stack[0] = -1;
	board.split_point = board.split_point_stack;
	board.split_point_stack[0] = NULL;

	/* Initialize the spin locks. */
	LOCK_INIT(smp_data->io_lock);
	LOCK_INIT(smp_data->lock);
	for (x = 0; x < procs; x++)
	{
		LOCK_INIT(smp_block[x].lock);
		LOCK_INIT(smp_block[x].input_lock);
	}
	for (x = 0; x < MAX_SPLIT_POINTS; x++)
	{
		LOCK_INIT(split_point[x].lock);
		LOCK_INIT(split_point[x].move_lock);
	}

	/* Now start the child processes. */
	for (x = 1; x < zct->process_count; x++)
	{
		/* Child process. */
		if ((y = fork()) == 0)
		{
			board.id = x;
			idle_loop(x);
		}
		/* Parent process. */
		else
		{
			smp_block[x].pid = y;
			smp_tell(x, SMP_INIT, 0);
		}
	}

	/* Set up the signals to use for the master processor. */
	if (board.id == 0)
	{
		signal(SIGINT, smp_cleanup_sig);
		signal(SIGTERM, smp_cleanup_sig);
//	signal(SIGCHLD, smp_cleanup_sig);
	}

	/* Now that the processors are spawned, make them idle until we start
		searching. */
	stop_child_processors();
}
コード例 #13
0
// *************************************************************************************************
// @fn          set_value
// @brief       Generic value setting routine
// @param       int32_t  * value						Pointer to value to set
//				uint8_tdigits						Number of digits
//				uint8_t blanks						Number of whitespaces before first valid digit
//				int32_t  limitLow					Lower limit of value
//				int32_t  limitHigh					Upper limit of value
//				uint16_t mode
//				uint8_t segments					Segments where value should be drawn
//				fptr_setValue_display_function1		Value-specific display routine
// @return      none
// *************************************************************************************************
void set_value(int32_t  * value, uint8_t digits, uint8_t blanks, int32_t  limitLow, int32_t  limitHigh, uint16_t mode, uint8_t segments, void (*fptr_setValue_display_function1)(uint8_t segments, uint32_t  value, uint8_t digits, uint8_t blanks, uint8_t disp_mode))
{
	uint8_t update;
	int16_t  stepValue;
	if((mode & SETVALUE_STEP_FIFE ) == SETVALUE_STEP_FIFE)
	{
		stepValue=5;
	}
	else
	{
		stepValue=1;
	}
	uint8_t doRound = 0;
	#ifdef CONFIG_STOP_WATCH
	uint8_t stopwatch_state;
	#endif
	uint32_t  val;
	int32_t  orig_val=*value;
	
	// Clear button flags
	button.all_flags = 0;
	
	// Clear blink memory
	clear_blink_mem();
	
	// For safety only - buzzer on/off and button_repeat share same IRQ
	stop_buzzer();
	
	#ifdef CONFIG_STOP_WATCH
	// Disable stopwatch display update while function is active
	stopwatch_state = sStopwatch.state;
	sStopwatch.state = STOPWATCH_HIDE;
	#endif
	
	// Init step size and repeat counter
	sButton.repeats = 0;
	
	// Initial display update
	update = 1;
	
	// Turn on 200ms button repeat function 
	button_repeat_on(200);
	
	// Start blinking with with 2Hz
	set_blink_rate(BIT6 + BIT5);
	
	// Value set loop
	while(1) 
	{
		// Idle timeout: exit function
		if (sys.flag.idle_timeout) break;

		// Button STAR (short) button: exit function
		if (button.flag.star) break;

		// NUM button: exit function and goto to next value (if available)
		if (button.flag.num)
		{
			if ((mode & SETVALUE_NEXT_VALUE) == SETVALUE_NEXT_VALUE) break;
		}

		// UP button: increase value
		if(button.flag.up)
		{
			// Increase value
			* value = * value + stepValue;
			
			// Check value limits
			if (* value > limitHigh) 
			{
				// Check if value can roll over, else stick to limit
				if ((mode & SETVALUE_ROLLOVER_VALUE) == SETVALUE_ROLLOVER_VALUE) 	* value = limitLow;
				else 																* value = limitHigh;				
					
				// Reset step size to default
				if((mode & SETVALUE_STEP_FIFE ) == SETVALUE_STEP_FIFE)
				{
					stepValue=5;
				}
				else
				{
					stepValue=1;
				}
			}

			// Trigger display update
			update = 1;
			
			// Clear button flag
			button.flag.up = 0;
		}
		
		// DOWN button: decrease value
		if(button.flag.down)
		{
			// Decrease value
			* value = * value - stepValue;
			
			// Check value limits
			if (* value < limitLow) 
			{
				// Check if value can roll over, else stick to limit
				if ((mode & SETVALUE_ROLLOVER_VALUE) == SETVALUE_ROLLOVER_VALUE)	* value = limitHigh;
				else																* value = limitLow;
					
				// Reset step size to default
				if((mode & SETVALUE_STEP_FIFE ) == SETVALUE_STEP_FIFE)
				{
					stepValue=5;
				}
				else
				{
					stepValue=1;
				}
			}

			// Trigger display update
			update = 1;

			// Clear button flag	
			button.flag.down = 0;
		}

		
		// When fast mode is enabled, increase step size if Sx button is continuously
		if ((mode & SETVALUE_FAST_MODE) == SETVALUE_FAST_MODE)
		{
			switch (sButton.repeats)
			{
				case 0:			if((mode & SETVALUE_STEP_FIFE ) == SETVALUE_STEP_FIFE){	stepValue=5;	doRound = 1; }	else {	stepValue=1;	doRound = 0; }	break;
				case 10:		
				case -10:		stepValue = 10;		doRound = 1; 	break;
				case 20:			
				case -20:		stepValue = 100;	doRound = 1; 	break;
				case 30:			
				case -30:		stepValue = 1000;	doRound = 1; 	break;
			}
			
			// Round value to avoid odd numbers on display
			if (stepValue != 1 && doRound == 1)	
			{
				* value -= * value % stepValue;
				doRound = 0;
			}
		}

		// Update display when there is new data
		if (update)
		{
			// Display up or down arrow according to sign of value
			if ((mode & SETVALUE_DISPLAY_ARROWS) == SETVALUE_DISPLAY_ARROWS)
			{
				if (* value >= 0)
				{
					display_symbol(LCD_SYMB_ARROW_UP, SEG_ON);
					display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
					val = *value;
				}
				else 
				{
					display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF);
					display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON);
					val = *value * (-1);
				}
			}
			else
			{
				val = *value;
			}
			
			if((mode & SETVALUE_DISPLAY_SYMBOL) == SETVALUE_DISPLAY_SYMBOL)
			{	
				display_symbol(segments,SEG_ON_BLINK_ON);
				// return when value is changed
				if( orig_val != *value ) break;
			}
			else if( (mode & SETVALUE_SWITCH_ARROWS) == SETVALUE_SWITCH_ARROWS )
			{
				//show up arrow if value is odd
				if( val & 0x1 )
				{
					display_symbol(LCD_SYMB_ARROW_UP,SEG_ON_BLINK_ON);
					display_symbol(LCD_SYMB_ARROW_DOWN,SEG_OFF_BLINK_OFF);
				}
				//show down arrow if value is even
				else
				{
					display_symbol(LCD_SYMB_ARROW_DOWN,SEG_ON_BLINK_ON);
					display_symbol(LCD_SYMB_ARROW_UP,SEG_OFF_BLINK_OFF);
				}
			}
			else
			{
				// Display function can either display value directly, modify value before displaying
				// or display a string referenced by the value
				fptr_setValue_display_function1(segments, val, digits, blanks, SEG_ON_BLINK_ON);
			}

			// Clear update flag
			update = 0;
		}
		
		// Call idle loop to serve background tasks
		idle_loop();
		
	}
	
	//switch symbol
	if((mode & SETVALUE_DISPLAY_SYMBOL) == SETVALUE_DISPLAY_SYMBOL)
	{
		display_symbol(segments,SEG_OFF);
	}
	
	// Set blinking rate to 1Hz and stop
	set_blink_rate(BIT7 + BIT6 + BIT5);
	clear_blink_mem();
	
	// Turn off button repeat function
	button_repeat_off();

	#ifdef CONFIG_STOP_WATCH
	// Enable stopwatch display updates again
	sStopwatch.state = stopwatch_state;
	#endif
}
コード例 #14
0
ファイル: thread.cpp プロジェクト: certik/chess
void ThreadsManager::split(Position& pos, SearchStack* ss, Value* alpha, const Value beta,
                           Value* bestValue, Depth depth, Move threatMove,
                           int moveCount, MovePicker* mp, bool pvNode) {
  assert(pos.is_ok());
  assert(*bestValue >= -VALUE_INFINITE);
  assert(*bestValue <= *alpha);
  assert(*alpha < beta);
  assert(beta <= VALUE_INFINITE);
  assert(depth > DEPTH_ZERO);
  assert(pos.thread() >= 0 && pos.thread() < activeThreads);
  assert(activeThreads > 1);

  int i, master = pos.thread();
  Thread& masterThread = threads[master];

  lock_grab(&mpLock);

  // If no other thread is available to help us, or if we have too many
  // active split points, don't split.
  if (   !available_slave_exists(master)
      || masterThread.activeSplitPoints >= MAX_ACTIVE_SPLIT_POINTS)
  {
      lock_release(&mpLock);
      return;
  }

  // Pick the next available split point object from the split point stack
  SplitPoint& splitPoint = masterThread.splitPoints[masterThread.activeSplitPoints++];

  // Initialize the split point object
  splitPoint.parent = masterThread.splitPoint;
  splitPoint.master = master;
  splitPoint.is_betaCutoff = false;
  splitPoint.depth = depth;
  splitPoint.threatMove = threatMove;
  splitPoint.alpha = *alpha;
  splitPoint.beta = beta;
  splitPoint.pvNode = pvNode;
  splitPoint.bestValue = *bestValue;
  splitPoint.mp = mp;
  splitPoint.moveCount = moveCount;
  splitPoint.pos = &pos;
  splitPoint.nodes = 0;
  splitPoint.ss = ss;
  for (i = 0; i < activeThreads; i++)
      splitPoint.is_slave[i] = false;

  masterThread.splitPoint = &splitPoint;

  // If we are here it means we are not available
  assert(masterThread.state != Thread::AVAILABLE);

  int workersCnt = 1; // At least the master is included

  // Allocate available threads setting state to THREAD_BOOKED
  for (i = 0; !Fake && i < activeThreads && workersCnt < maxThreadsPerSplitPoint; i++)
      if (i != master && threads[i].is_available_to(master))
      {
          threads[i].state = Thread::BOOKED;
          threads[i].splitPoint = &splitPoint;
          splitPoint.is_slave[i] = true;
          workersCnt++;
      }

  assert(Fake || workersCnt > 1);

  // We can release the lock because slave threads are already booked and master is not available
  lock_release(&mpLock);

  // Tell the threads that they have work to do. This will make them leave
  // their idle loop.
  for (i = 0; i < activeThreads; i++)
      if (i == master || splitPoint.is_slave[i])
      {
          assert(i == master || threads[i].state == Thread::BOOKED);

          threads[i].state = Thread::WORKISWAITING; // This makes the slave to exit from idle_loop()

          if (useSleepingThreads && i != master)
              threads[i].wake_up();
      }

  // Everything is set up. The master thread enters the idle loop, from
  // which it will instantly launch a search, because its state is
  // THREAD_WORKISWAITING.  We send the split point as a second parameter to the
  // idle loop, which means that the main thread will return from the idle
  // loop when all threads have finished their work at this split point.
  idle_loop(master, &splitPoint);

  // We have returned from the idle loop, which means that all threads are
  // finished. Update alpha and bestValue, and return.
  lock_grab(&mpLock);

  *alpha = splitPoint.alpha;
  *bestValue = splitPoint.bestValue;
  masterThread.activeSplitPoints--;
  masterThread.splitPoint = splitPoint.parent;
  pos.set_nodes_searched(pos.nodes_searched() + splitPoint.nodes);

  lock_release(&mpLock);
}