コード例 #1
0
ファイル: client_interface.c プロジェクト: NVIDIA/ptp-nsight
int
DbgStartSession(session *s, char *exe, char *path, char *args)
{
	int				res;
	int				len;
	unsigned char *	buf;
	bitset *		procs = bitset_new(s->sess_procs);
	proxy_msg *		msg = new_proxy_msg(DBG_STARTSESSION_CMD, 0);

	proxy_msg_add_int(msg, SERVER_TIMEOUT);
	proxy_msg_add_string(msg, exe);
	proxy_msg_add_string(msg, path);
	proxy_msg_add_string(msg, args);
	proxy_serialize_msg(msg, &buf, &len);

	/*
	 * Create a bitset containing all processes
	 */
	bitset_invert(procs);

	res = send_command(procs, DBG_EV_WAITALL, buf, len, NULL);

	free_proxy_msg(msg);
	bitset_free(procs);
	
	return res;
}
コード例 #2
0
int main (int argc, char **argv) {
  int i,j;

  for (i=1; i<SBS_NUM_TESTS; i++) {
    uint32_t nbits = i;
    bitset_set_max_num_elements(nbits);
    printf ("\n\ni=%d nb=%d\n", i, nbits);
    uint32_t num_bs = SBS_NUM_TESTS;
    BitSet *bs;  //  = (BitSet *) my_malloc(sizeof(BitSet) * num_bs);
    bs = bitset_new();
    /*
    for (j=0; j<num_bs; j++) {
      bs[j] = bitset_new();
    }    
    */
    for (j=0; j<nbits * SBS_DUNNO ; j++) {
      printf ("j=%d\n", j);
      int element = rand() % nbits;
      printf ("set %d\n", element);
      bitset_add(bs,element);
      assert (bitset_member(bs,element));
      bitset_spit(bs);
      printf ("\n");
      element = rand() % nbits;
      printf ("unset %d\n", element);
      bitset_remove(bs,element);
      assert (!(bitset_member(bs,element)));
      bitset_spit(bs);
      printf ("\n");
    }
    bitset_free(bs);
  }
}	     
コード例 #3
0
ファイル: bitset_demo.c プロジェクト: SerhoLiu/libakio
int main(int argc, char **argv)
{
    bitset *set;
    set = bitset_new(50);
    if (set == NULL) return 0;

    init_array();
    printf("A: \n");
    print_array(A, 20);
    printf("B: \n");
    print_array(B, 20);

    int i, j, common[20];
    for (i = 0; i < 20; i++) {
        bitset_set(set, A[i], 1);
    }

    j = 0;
    for (i = 0; i < 20; i++) {
        if (bitset_get(set, B[i])) {
            common[j++] = B[i];
        }
    }

    printf("Common: \n");
    print_array(common, j);

    bitset_free(set);
    
    return 0;
}
コード例 #4
0
ファイル: reg_alloc.c プロジェクト: scrossuk/ancient-code
void initialise(rd_vlist * vlist, unsigned int reg_num){
	precoloured      = rga_node_list_new();
	initial          = rga_node_list_new();
	simplifyWorklist = rga_node_list_new();
	freezeWorklist   = rga_node_list_new();
	spillWorklist    = rga_node_list_new();
	spilledNodes     = rga_node_list_new();
	coalescedNodes   = rga_node_list_new();
	colouredNodes    = rga_node_list_new();
	selectStack      = rga_node_list_new();

	coalescedMoves   = rga_move_list_new();
	constrainedMoves = rga_move_list_new();
	frozenMoves      = rga_move_list_new();
	worklistMoves    = rga_move_list_new();
	activeMoves      = rga_move_list_new();

	num_nodes = vlist->num_vars + reg_num;
	
	nodes = new rga_node *[num_nodes];
	adjSet = new bitset *[num_nodes];
	adjList = new rga_node_map *[num_nodes];
	degree = new unsigned int[num_nodes];
	moveList = new rga_move_map *[num_nodes];
	alias = new rga_node *[num_nodes];
	colour = new unsigned char[num_nodes];

	rd_var * v;
	unsigned int i;

	for(i = 0; i < vlist->num_vars; i++){
		v = rd_vlist_find(vlist, i);
		nodes[i] = rga_node_new(v);
		#ifdef DEBUG_MODE
		printf("Var %u has v%u\n", i, nodes[i]->id);
		#endif
		rga_node_list_push(initial, nodes[i]);
		nodes[i]->set = RGA_INITIAL;
		colour[i] = 0;
	}

	for(i = 0; i < reg_num; i++){
		colour[vlist->num_vars + i] = (i+1);
		nodes[vlist->num_vars + i] = rga_node_new(0);
		#ifdef DEBUG_MODE
		printf("Reg %u has v%u\n", vlist->num_vars + i, nodes[vlist->num_vars + i]->id);
		#endif
		nodes[vlist->num_vars + i]->set = RGA_PRECOLOURED;
		rga_node_list_push(precoloured, nodes[vlist->num_vars + i]);
	}
	
	for(i = 0; i < num_nodes; i++){
		degree[i] = 0;
		adjList[i] = 0;
		adjSet[i] = bitset_new(num_nodes);
		moveList[i] = 0;
		alias[i] = 0;
	}
}
コード例 #5
0
// create a new labelset and return it
// NB: this function allocates memory. caller is responsible for freeing.
static SB_INLINE LabelSet *labelset_new(void) {
    LabelSet *ls;
    ls = (LabelSet *) my_calloc(1, sizeof(LabelSet), poolid_label_set);
    ls->set = bitset_new();
    ls->type = LST_DUNNO;
    ls->count = 1;
    return ls;
}
コード例 #6
0
ファイル: bitset.c プロジェクト: SUSE/accelio
bitset *bitset_dup(bitset *b)
{
	bitset *nb = bitset_new(b->bs_nbits);

	bitset_copy(nb, b);

	return nb;
}
コード例 #7
0
/*Parse a string, writting the elements to a bitset
  Return the bitset */
struct bitset * parse_string(char *input){
  struct bitset * result;
  result = bitset_new(256);

  int i;
  for(i =0;input[i] != '\0'; i++){
    bitset_add(result,input[i]);
  }
  return result;
}
コード例 #8
0
ファイル: condition.c プロジェクト: arpa2/steamworks
/* Check that all conditions refer to at least one variable; it is silly to
 * have a constant-based (or context-free) expression to filter information
 * that passes through Pulley.
 * Return NULL if all are bound; otherwise return the variables
 * that are not bound.
 */
bitset_t *cndtab_invariant_conditions (struct cndtab *tab) {
	bitset_t *retval = NULL;
	cndnum_t i;
	for (i=0; i<tab->count_cnds; i++) {
		if (bitset_isempty (tab->cnds [i].vars_needed)) {
			// Error found
			if (retval == NULL) {
				retval = bitset_new (&tab->cndtype);
			}
			bitset_set (retval, i);
		}
	}
	return retval;
}
コード例 #9
0
ファイル: bitset.c プロジェクト: tkawachi/bitset-rb
static VALUE rb_bitset_not(VALUE self) {
    Bitset * bs = get_bitset(self);

    Bitset * new_bs = bitset_new();
    bitset_setup(new_bs, bs->len);

    int max = ((bs->len-1) >> 6) + 1;
    int i;
    for(i = 0; i < max; i++) {
        uint64_t segment = bs->data[i];
        new_bs->data[i] = ~segment;
    }

    return Data_Wrap_Struct(cBitset, 0, bitset_free, new_bs);
}
コード例 #10
0
ファイル: bitset.c プロジェクト: SUSE/accelio
/**
 * Convert string into a bitset. Inverse of bitset_to_str().
 *
 */
bitset *str_to_bitset(char *str, char **end)
{
	int			nbits = 0;
	int			bytes;
	int			n;
	int			pos;
	int			b;
        int                     len;
	bitset                  *bp;
        char                    dst[1024];

        if (!str)
                return NULL;

        /* hex string has 0x prefix */
        if (str[0] == '0' && str[1] == 'x')
                str = str + 2;

        len = strlen(str);
        if (len % 2) {
                nbits = (len + 1) << 2;
                bytes = NUM_BYTES(nbits);
                pos = (bytes << 3) - 5;
        } else {
                nbits = len << 2;
                bytes = NUM_BYTES(nbits);
                pos = (bytes << 3) - 1;
        }

        if (0)
                hex2binary(str, dst);

	bp = bitset_new(nbits);

	for (; *str != '\0' && isxdigit(*str) && pos >= 0; str++) {
		b = digittoint(*str);
		for (n = 3; n >= 0; n--, pos--) {
			if (b & (1 << n)) {
				bitset_set(bp, pos);
			}
		}
	}

	if (end != NULL)
                *end = str - 1;

	return bp;
}
コード例 #11
0
ファイル: bitset.c プロジェクト: tkawachi/bitset-rb
static VALUE rb_bitset_from_s(VALUE self, VALUE s) {
    int length = RSTRING_LEN(s);
    char* data = StringValuePtr(s);

    Bitset * new_bs = bitset_new();
    bitset_setup(new_bs, length);

    int i;
    for (i = 0; i < length; i++) {
        if (data[i] == '1') {
            set_bit(new_bs, i);
        }
    }

    return Data_Wrap_Struct(cBitset, 0, bitset_free, new_bs);
}
コード例 #12
0
ファイル: condition.c プロジェクト: arpa2/steamworks
cndnum_t cnd_new (struct cndtab *tab) {
	struct condition *newcnd;
	if (tab->count_cnds >= tab->allocated_cnds) {
		int alloc = tab->allocated_cnds + 100;
		struct condition *newcnds;
		newcnds = realloc (tab->cnds, alloc * sizeof (struct condition));
		if (newcnds == NULL) {
			fatal_error ("Out of memory allocating condition");
		}
		tab->cnds = newcnds;
		tab->allocated_cnds = alloc;
	}
	newcnd = &tab->cnds [tab->count_cnds];	/* Incremented on return */
	newcnd->weight = 0.1;	/* Default setting */
	newcnd->vars_needed = bitset_new (tab->vartype);
	newcnd->calc = NULL;
	newcnd->calclen = 0;
	return tab->count_cnds++;
}
コード例 #13
0
ファイル: client_interface.c プロジェクト: NVIDIA/ptp-nsight
/*
 * Session initialization
 */
int
DbgInit(session **sess, int argc, char *argv[])
{
	session *		s;
	
	*sess = s = (session *)malloc(sizeof(session));
	
	if (sdm_init(argc, argv) < 0) {
		return -1;
	}

	s->sess_procs = sdm_route_get_size() - 1;

	tmp_idset = sdm_set_new();
	tmp_bitset = bitset_new(s->sess_procs);

	sdm_aggregate_set_completion_callback(session_event_handler, (void *)s);

	return 0;
}
コード例 #14
0
ファイル: bitset.c プロジェクト: tkawachi/bitset-rb
static VALUE rb_bitset_xor(VALUE self, VALUE other) {
    Bitset * bs = get_bitset(self);
    Bitset * other_bs = get_bitset(other);

    Bitset * new_bs = bitset_new();
    bitset_setup(new_bs, MIN(bs->len, other_bs->len));

    int max = ((bs->len-1) >> 6) + 1;
    int other_max = ((other_bs->len-1) >> 6) + 1;
    max = MIN(max, other_max);

    int i;
    for(i = 0; i < max; i++) {
        uint64_t segment = bs->data[i];
        uint64_t other_segment = other_bs->data[i];
        new_bs->data[i] = segment ^ other_segment;
    }

    return Data_Wrap_Struct(cBitset, 0, bitset_free, new_bs);
}
コード例 #15
0
ファイル: client_interface.c プロジェクト: NVIDIA/ptp-nsight
int
DbgQuit(session *s)
{
	int				res;
	int				len;
	unsigned char *	buf;
	bitset *		procs = bitset_new(s->sess_procs);
	proxy_msg *		msg = new_proxy_msg(DBG_QUIT_CMD, 0);

	proxy_serialize_msg(msg, &buf, &len);

	bitset_invert(procs);

	res = send_command(procs, DBG_EV_WAITALL, buf, len, NULL);

	free_proxy_msg(msg);
	bitset_free(procs);

	return res;
}
コード例 #16
0
ファイル: reg_alloc.c プロジェクト: scrossuk/ancient-code
void assign_colours(){
	rga_node * node;
	rga_node_map * map;
	rga_node * w;
	bitset * used_colours = bitset_new(num_registers);
	while(node = rga_node_list_pop(selectStack)){
		bitset_reset(used_colours);
		map = adjList[node->id];
		while(map != 0){
			w = get_alias(map->node);
			if(w->set == RGA_COLOURED_NODES || w->set == RGA_PRECOLOURED){
				bitset_set(used_colours, colour[w->id]-1);
			}
			map = map->prev;
		}
		if(bitset_all_on(used_colours)){
			rga_node_list_push(spilledNodes, node);
			#ifdef DEBUG_MODE
			printf("Node v%u has become an actual spill\n", node->id);
			#endif
			node->set = RGA_SPILLED_NODES;
		}else{
			rga_node_list_push(colouredNodes, node);
			node->set = RGA_COLOURED_NODES;
			colour[node->id] = bitset_first_off(used_colours, 0) + 1;
			#ifdef DEBUG_MODE
			printf("v%u = reg%u\n", node->id, colour[node->id]-1);
			#endif
		}
	}
	w = coalescedNodes->end;
	while(w != 0){
		colour[w->id] = colour[get_alias(w)->id];
		w = w->prev;
	}
}
コード例 #17
0
ファイル: master_cmds.c プロジェクト: NVIDIA/ptp-nsight
int
DbgMasterInit(int num_svrs, int my_id, char *name, proxy_svr_helper_funcs *funcs, proxy_commands *cmds)
{
	struct timeval	tv = { 0, CLIENT_TIMEOUT };

	DEBUG_PRINTF(DEBUG_LEVEL_MASTER, "DbgMasterInit num_svrs=%d\n", num_svrs);

	tmp_idset = sdm_set_new();
	tmp_bitset = bitset_new(num_svrs);

	/*
	 * Register callback
	 */
	sdm_aggregate_set_completion_callback(dbg_master_cmd_completed, NULL);

	/*
	 * Create a bitset containing all processes
	 */
	dbg_procs = sdm_set_new();
	sdm_set_add_all(dbg_procs, num_svrs-1);

	/*
	 * Reset state
	 */
	dbg_state = RUNNING;

	/*
	 * Initialize proxy
	 */
	if (proxy_svr_init(name, &tv, funcs, cmds, &dbg_proxy) != PTP_PROXY_RES_OK) {
		DbgSetError(DBGERR_DEBUGGER, proxy_get_error_str());
		return DBGRES_ERR;
	}

	return DBGRES_OK;
}
コード例 #18
0
ファイル: reg_alloc.c プロジェクト: scrossuk/ancient-code
rd_vlist * mem_alloc(rd_instr * code,
	rd_vlist * vlist,
	unsigned int match_types,
	unsigned int ret_type,
	unsigned int type_size){

	//start local variables
	flow_graph * graph;
	flow_node * node;

	rga_node * x, * y;
	rga_node_map * list;
	rga_move * move;

	rd_vlist * new_list;
	rd_instr * ins;
	rd_var * v;

	bitset * live;

	unsigned int def_pos, live_pos, set_size, last_id, i;

	bitset * used_colours;
	//end local variables
	
	//perform flow analysis
	graph = flow_generate_graph(code, vlist, 0, 0, match_types);

	//allocate space for node and move information
	initial          = rga_node_list_new();
	coalescedNodes   = rga_node_list_new();
	colouredNodes    = rga_node_list_new();

	coalescedMoves   = rga_move_list_new();
	constrainedMoves = rga_move_list_new();
	worklistMoves    = rga_move_list_new();
	
	nodes = new rga_node *[vlist->num_vars];
	adjSet = new bitset *[vlist->num_vars];
	adjList = new rga_node_map *[vlist->num_vars];
	alias = new rga_node *[vlist->num_vars];
	colour = new unsigned char[vlist->num_vars];

	//initialise memory variables
	for(i = 0; i < vlist->num_vars; i++){
		nodes[i] = rga_node_new(0);
		rga_node_list_push(initial, nodes[i]);
		nodes[i]->set = RGA_INITIAL;
		colour[i] = 0;
		adjList[i] = 0;
		adjSet[i] = bitset_new(vlist->num_vars);
		alias[i] = 0;
	}

	//build the graph
	node = graph->end;
	def_pos = live_pos = 0;
	while(node != 0){
		ins = node->data;
		live = bitset_copy(node->liveout);
		if(ins->type == RD_SET && ins->p1->type & match_types && ins->p2->type & match_types){
			bitset_sub(live, node->use);
			if(!rga_move_list_exists(worklistMoves, nodes[ins->p1->id], nodes[ins->p2->id])){
				move = rga_move_new(nodes[ins->p1->id], nodes[ins->p2->id]);
				rga_move_list_push(worklistMoves, move);
				move->set = RGA_WORKLIST_MOVES;
			}
		}
		bitset_or(live, node->def);
		while((def_pos = bitset_first_on(node->def, def_pos)) != ~0){
			while((live_pos = bitset_first_on(live, live_pos)) != ~0){
				mem_add_edge(nodes[live_pos], nodes[def_pos]);
				live_pos++;
			}
			live_pos = 0;
			def_pos++;
		}
		def_pos = 0;
		node = node->prev;
	}

	//coalesce phase
	while(!rga_move_list_isempty(worklistMoves)){
		move = rga_move_list_pop(worklistMoves);
		x = get_alias(move->a);
		y = get_alias(move->b);
		if(x == y){
			rga_move_list_push(coalescedMoves, move);
			move->set = RGA_COALESCED_MOVES;
		}else if(bitset_check(adjSet[x->id], y->id) || bitset_check(adjSet[x->id], y->id)){
			rga_move_list_push(constrainedMoves, move);
			move->set = RGA_CONSTRAINED_MOVES;
		}else{
			rga_move_list_push(coalescedMoves, move);
			move->set = RGA_COALESCED_MOVES;
			list = adjList[y->id];
			rga_node_list_remove(initial, y);
			rga_node_list_push(coalescedNodes, y);
			y->set = RGA_COALESCED_NODES;
			alias[y->id] = x;
			while(list != 0){
				if(list->node->set != RGA_COALESCED_NODES){
					mem_add_edge(list->node, x);
				}
				list = list->prev;
			}
		}
	}

	//simplify and select phase
	new_list = rd_varlist(0);
	set_size = 0;
	last_id = 0;
	used_colours = bitset_new(vlist->num_vars);
	while(x = rga_node_list_pop(initial)){
		bitset_reset(used_colours);
		list = adjList[x->id];
		while(list != 0){
			y = get_alias(list->node);
			if(y->set == RGA_COLOURED_NODES){
				bitset_set(used_colours, colour[y->id]);
			}
			list = list->prev;
		}
		rga_node_list_push(colouredNodes, x);
		x->set = RGA_COLOURED_NODES;
		colour[x->id] = bitset_first_off(used_colours, 0);
		if(rd_vlist_find(new_list, colour[x->id]) == 0){
			rd_vlist_add(new_list, colour[x->id], ret_type, 0, 0, type_size);
		}
		if(colour[x->id] > last_id){
			last_id = colour[x->id];
		}
		#ifdef DEBUG_MODE
		printf("mem%u gets %u\n", x->id, colour[x->id]);
		#endif
	}
	bitset_delete(used_colours);

	new_list->num_vars = last_id + 1;

	//set the colour of coalesced nodes
	x = coalescedNodes->end;
	while(x != 0){
		colour[x->id] = colour[get_alias(x)->id];
		//rd_vlist_add(new_list, colour[x->id], ret_type, 0, 0, type_size);
		#ifdef DEBUG_MODE		
		printf("mem%u gets %u\n", x->id, colour[x->id]);
		#endif
		x = x->prev;
	}

	node = graph->end;
	while(node != 0){
		if(node->data->p1 != 0){
			if(node->data->p1->type & match_types){
				v = rd_vlist_find(new_list, colour[node->data->p1->id]);
				if(v != 0){
					node->data->p1 = v;
				}
			}
		}
		if(node->data->p2 != 0){
			if(node->data->p2->type & match_types){
				v = rd_vlist_find(new_list, colour[node->data->p2->id]);
				if(v != 0){
					node->data->p2 = v;
				}
			}
		}
		if(node->data->p3 != 0){
			if(node->data->p3->type & match_types){
				v = rd_vlist_find(new_list, colour[node->data->p3->id]);
				if(v != 0){
					node->data->p3 = v;
				}
			}
		}
		node = node->prev;
	}

	//clean up
	delete initial;
	delete coalescedNodes;
	delete colouredNodes;

	delete coalescedMoves;
	delete constrainedMoves;
	delete worklistMoves;

	for(i = 0; i < vlist->num_vars; i++){
		delete nodes[i];
		if(adjList[i] != 0){
			delete adjList[i];
		}
		bitset_delete(adjSet[i]);
	}

	delete[] nodes;
	delete[] adjSet;
	delete[] adjList;
	delete[] alias;
	delete[] colour;

	rga_reset();

	return new_list;
}
コード例 #19
0
ファイル: bitset.c プロジェクト: tkawachi/bitset-rb
static VALUE rb_bitset_alloc(VALUE klass) {
    VALUE obj;
    obj = Data_Wrap_Struct(klass, 0, bitset_free, bitset_new());
    return obj;
}
コード例 #20
0
int main()
{
    char input1[MAX_SIZE];
    char input2[MAX_SIZE];

    printf("%s\n", "Enter the first line of input:");
    fgets(input1, MAX_SIZE, stdin);

    printf("%s\n", "Enter the second line of input:");
    fgets(input2, MAX_SIZE, stdin);

    struct bitset * set1;
    set1 = bitset_new(MAX_SIZE);

    struct bitset * set2;
    set2 = bitset_new(MAX_SIZE);

    // Create bitsets for the result of
    // union & intersection function calls
    struct bitset * union_result_set;
    union_result_set = bitset_new(MAX_SIZE);

    struct bitset * intersect_result_set;
    intersect_result_set = bitset_new(MAX_SIZE);

    // Can't accept the newline bit, but it was being
    // set each time the fgets call was made and being added

    // Add all the input from string to set1
    for(int i = 0; input1[i] != '\0'; i++){
        if(input1[i] != '\n')
            bitset_add(set1, input1[i]);
    }

    // Add all the input from string to set2
    for(int i = 0; input2[i] != '\0'; i++){
        if(input2[i] != '\n')
            bitset_add(set2, input2[i]);
    }

    bitset_union(union_result_set, set1, set2);

    bitset_intersect(intersect_result_set, set1, set2);

    // Some quick testing I did to make sure things worked
    // Required me to manually enter the desired chars

    // Test adding, removal and lookup
//    printf("Lookup for '2' = %d, expected 1\n", bitset_lookup(set1, '2'));
//    printf("Remove for '2' = %d, expected 1\n", bitset_remove(set1, '2'));
//    printf("Lookup for '2' = %d, expected 0\n", bitset_lookup(set1, '2'));
//
//    printf("Lookup for '3' = %d, expected 1\n", bitset_lookup(set1, '3'));
//    printf("Remove for '3' = %d, expected 1\n", bitset_remove(set1, '3'));
//    printf("Lookup for '3' = %d, expected 0\n", bitset_lookup(set1, '3'));

//     Test union
//    printf("Lookup for '1' = %d, expected 1\n", bitset_lookup(union_result_set, '1'));
//    printf("Lookup for '2' = %d, expected 1\n", bitset_lookup(union_result_set, '2'));
//
//     Test intersection
//    printf("Lookup for '1' = %d, expected 1\n", bitset_lookup(intersect_result_set, '1'));
//    printf("Lookup for '2' = %d, expected 1\n", bitset_lookup(intersect_result_set, '2'));
//    printf("Lookup for '3' = %d, expected 0\n", bitset_lookup(intersect_result_set, '3'));

//    printf("%s\n", "Set 1:");
//    bitset_print(set1);
//
//    printf("%s\n", "Set 2:");
//    bitset_print(set2);
    bitset_print(union_result_set);
    bitset_print(intersect_result_set);

    return 0;
}
コード例 #21
0
ファイル: condition.c プロジェクト: arpa2/steamworks
/* This is a complex, recursive function to determine the cost for
 * calculating a condition after any still-needed variables have been
 * generated.  Cost is measured in terms of the anticipated number of
 * generated new variable sets, as provided by "*float" annotations
 * on generator and condition lines.
 *
 * Call this with a condition and varsneeded.  The soln_xxx fields will
 * be filled with the requested information, namely the total cost
 * and the generators needed to get there.  The soln_generators bitset
 * is assumed to already exist.
 *
 * This function may not always be able to determine a solution; this
 * can be the case if variables are mentioned in conditions but not in
 * generators, for instance.  In such situations, the function returns
 * false.  It is considered a success if all variables that are needed
 * for a condition are resolved by at least one generator.
 *
 * This is an important function when determining the "path of least
 * resistence" from any generator activity; the least costly condition
 * will always be calculated first, then the calculations are redone,
 * and what is then the least will be selected, and so on.  The
 * generators required will be inserted into the path before their
 * dependent conditions, in the order of least-costly ones first.
 *
 * This is a rather heavy form of analysis, but it is executed only
 * once, at startup of the environment.  After that, the SyncRepl
 * updates can ripple through in great speed.  Note that the complexity
 * and time delays of these procedures rise with the (usually modest)
 * degree of interrelationships between generators and conditions.
 */
bool cnd_get_min_total_cost (struct condition *cc, bitset_t *varsneeded,
				float *soln_mincost,
				bitset_t *soln_generators) {
	bool have_soln = false;
	float soln_mincost;
	varnum_t v, v_max;
	gennum_t g, g_max;
	//
	// Allocate bitsets that will be used while cycling, but not
	// across recursive uses.  To that and, a pile or pool of
	// bitsets could come in handy...  TODO: Optimisation
	//
	bitset_t *cand_varsneeded = bitset_new (varsneeded->type);
	bitset_t *cand_generators = bitset_new (soln_generators->type);
	//
	// If there is no need for further variables to calculate this
	// condition, then terminate recursion on this function.  There
	// will be no requirement to include a generator, and so there
	// will be no generator-incurred expenses.  There will only be
	// the cost of the condition itself, which must still compare
	// with other conditions that might be tighter.
	//
	if (bitset_isempty (varsneeded)) {
		/* Recursion ends, so neither generators nor their cost */
		bitset_empty (out_generators);
		return cc->cost;
	}
	//
	// Iterate over the variables that will need to be generated.
	// For each, iterate over the generators producing it.
	// See how this reduces the variable need, and recurse.
	//
	v_max = bitset_max (varsneeded);
	for (v=0; v<v_max; v++) {
		//
		// Skip this loop iteration if v is not actually needed.
		//
		if (!bitset_test (varsneeded, v)) {
			continue;
		}
		//
		// Iterate over generators for this variable.
		// Note that there may be none left?
		//
		bitset_t *vargenerators;
		vargenerators = var_share_generators (cc->vartab, v);
		g_max = bitset_max (vargenerators);
		if (g_max = BITNUM_BAD) {
			// Apparently, there are no generators for v
			// Skip for-loop (and trouble looping to BITNUM_BAD).
			continue;
		}
		for (g=0; g<g_max; g++) {
			bitset_t *cand_generators = NULL;
			bitset_t *generatorvars;
			float cand_cost;
			//
			// Reduce the variable need.
			//
			cand_varsneeded = bitset_copy (varsneeded);
			generatorvars = gen_share_variables (v);
			bitset_subtract (cand_varsneeded, generatorvars);
			//
			// Determine the cost for generating the remainder.
			//
			if (!cnd_get_cost_total (
					cc, cand_varsneeded,
					&cand_cost, cand_generators)) {
				continue;
			}
			cand_mincost *= generator_cost (g);
			if (have_soln && (cand_cost > soln_mincost)) {
				continue;
			}
			tmp_generators = soln_generators;
			soln_generators = cand_generators;
			cand_generators = tmp_generators; // Reuse in loops
			bitset_set (soln_generators, g);
			soln_mincost = cand_mincost;
			have_soln = true;
		}
	}
	//
	// Cleanup temporary allocations.
	//
	bitset_destroy (cand_varsneeded);
	bitset_destroy (cand_generators);
	//
	// Collect results.  Return success only if we do indeed have
	// found a solution.
	//
	return have_soln;
}
コード例 #22
0
// return a new bitset containing the union of bs1 and bs2 
static SB_INLINE BitSet *bitset_union(BitSet *bs1, BitSet *bs2) {
  BitSet *bs_new = bitset_new();
  bitset_collect(bs_new, bs1);
  bitset_collect(bs_new, bs2);
  return bs_new;
}