static cache_vars_t* cache_init(int size,int sector){ int num; cache_vars_t* s=shared_alloc(sizeof(cache_vars_t)); if(s==NULL) return NULL; memset(s,0,sizeof(cache_vars_t)); num=size/sector; if(num < 16){ num = 16; }//32kb min_size s->buffer_size=num*sector; s->sector_size=sector; s->buffer=shared_alloc(s->buffer_size); if(s->buffer == NULL){ shared_free(s, sizeof(cache_vars_t)); return NULL; } s->fill_limit=8*sector; s->back_size=s->buffer_size/2; #if FORKED_CACHE s->ppid = getpid(); #endif return s; }
/** 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(); }