static void *coalesce(void *bp) { size_t prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp))); size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp))); size_t size = GET_SIZE(HDRP(bp)); if(prev_alloc && next_alloc) //101 { add_free(bp); //return bp; } else if(prev_alloc && !next_alloc) //100 { rm_free(NEXT_BLKP(bp)); size += GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); add_free(bp); } else if(!prev_alloc && next_alloc) //001 { size += GET_SIZE(HDRP(PREV_BLKP(bp))); PUT(FTRP(bp), PACK(size, 0)); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); } else //000 { rm_free(NEXT_BLKP(bp)); size += GET_SIZE(HDRP(NEXT_BLKP(bp))) + GET_SIZE(HDRP(PREV_BLKP(bp))); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); } return bp; }
/* used in realloc */ static void *replace(void *bp, size_t asize) { size_t csize = GET_SIZE(HDRP(bp)); if((csize - asize) >= (2 * DSIZE)) { //contain old block data PUT(HDRP(bp), PACK(asize, 1)); PUT(FTRP(bp), PACK(asize, 1)); void *p = NEXT_BLKP(bp); PUT(HDRP(p), PACK((csize - asize), 0)); PUT(FTRP(p), PACK((csize - asize), 0)); add_free(p); return bp; } else return bp; //no action }
/************************************************************* * move a block of memory from the data chain to the free chain * merge with next & previous blocks if possible */ static void release_block( register tMemHdr *tr ) { register tMemHdr *t0; register tMemHdr *t1; assert( tr == NULL || tr->next_mem == NULL || tr->next_mem->prev_mem == tr ); assert( tr == NULL || tr->prev_mem == NULL || tr->prev_mem->next_mem == tr ); assert( tr == NULL || tr->next_list == NULL || tr->next_list->prev_list == tr ); assert( tr == NULL || tr->prev_list == NULL || tr->prev_list->next_list == tr ); assert( check_block(tr) ); assert( ISDATA(tr) ); total_free += tr->size; total_used -= tr->size; *tr->pbase = NULL; /* tell application this block has been released */ tr->pbase = NULL; /* flag this block as free */ t0 = tr->prev_list; t1 = tr->next_list; if( t0 == NULL ) { head_data = t1; } else { t0->next_list = t1; } /* if */ if( t1 == NULL ) { tail_data = t0; } else { t1->prev_list = t0; } /* if */ /** block removed from data chain, now try merge with next, previous **/ t1 = tr->next_mem; if( t1 != NULL && ISFREE(t1) ) { /** we can absorb the next mem block **/ #ifdef TEST merged_next++; dprintf(( "merging block(%ld, size %ld) & following(%ld, size %ld)\n", (long)tr->data[0], (long)tr->size, (long)tr->next_mem->data[0], (long)tr->next_mem->size )); #endif rem_free( t1 ); /** remove next from free list **/ /** remove tr->next_mem from memory list **/ tr->size += t1->size + sizeof(tMemHdr); tr->next_mem = t0 = t1->next_mem; if( t0 != NULL ) { t0->prev_mem = tr; } /* if */ assert( tr->next_mem == NULL || tr->next_mem->prev_mem == tr ); assert( tr->next_mem == NULL || (uint32)tr + sizeof(tMemHdr) + tr->size == (uint32)tr->next_mem ); dprintf(( "size of merged block is %ld\n", (long)tr->size )); total_free += sizeof( tMemHdr ); nr_blocks--; } /* if */ assert( total_free + total_used + (nr_blocks-1)*sizeof(tMemHdr) == total_size ); t0 = tr->prev_mem; if( t0 != NULL && ISFREE(t0) ) { /** we can merge into the prev mem block **/ #ifdef TEST dprintf(( "merging block(%ld, size %ld) & previous(%ld, size %ld)\n", (long)tr->data[0], (long)tr->size, (long)tr->prev_mem->data[0], (long)tr->prev_mem->size )); merged_prev++; #endif rem_free( t0 ); /** remove prev from free list **/ /** remove tr from memory list **/ t1 = t0->next_mem = tr->next_mem; if( t1 != NULL ) { t1->prev_mem = t0; } /* if */ assert( t0->next_mem == NULL || t0->next_mem->prev_mem == t0 ); assert( t1 == NULL || t1->prev_mem->next_mem == t1 ); t0->size += tr->size + sizeof( tMemHdr ); total_free += sizeof( tMemHdr ); nr_blocks--; tr = t0; /* tr is adr of merged block */ dprintf(( "size of merged block is %ld\n", (long)tr->size )); assert( tr->next_mem == NULL || (uint32)tr + sizeof(tMemHdr) + tr->size == (uint32)tr->next_mem ); assert( tr->next_mem == NULL || tr->next_mem->prev_mem == tr); } /* if */ assert( total_free + total_used + (nr_blocks-1)*sizeof(tMemHdr) == total_size ); add_free( tr ); assert( check_cache() ); } /* release_block() */
int Compass_write_sigref(NuSMVEnv_ptr env, BddFsm_ptr fsm, FILE* sigref_file, FILE* prob_file, /* can be NULL */ FILE* ap_file, /* can be NULL */ Expr_ptr tau, /* can be NULL */ boolean do_indent /* Beautify the XML output */ ) { BddEnc_ptr enc = BddFsm_get_bdd_encoding(fsm); DDMgr_ptr dd = BddEnc_get_dd_manager(enc); const NodeMgr_ptr nodemgr = NODE_MGR(NuSMVEnv_get_value(env, ENV_NODE_MGR)); const TypeChecker_ptr tc = BaseEnc_get_type_checker(BASE_ENC(enc)); NodeList_ptr ap_list_add = NODE_LIST(NULL); NodeList_ptr probs_list = NULL; NodeList_ptr ap_list = NULL; int retval = 0; add_ptr prob_add; add_ptr init_add; add_ptr trans_add; add_ptr tau_add; bdd_ptr bdd_trans; bdd_ptr state_mask = NULL; bdd_ptr input_mask = NULL; bdd_ptr next_state_mask = NULL; bdd_ptr next_and_curr_state_mask = NULL; /* preprocessing of the parameters */ /* tau */ if (EXPR(NULL) != tau) { tau = Compile_FlattenSexp(BaseEnc_get_symb_table(BASE_ENC(enc)), car(tau) /* gets rid of SIMPWFF */, Nil); } /* prob_file */ if (NULL != prob_file) { ParserProb_ptr pl_parser = NULL; pl_parser = ParserProb_create(env); ParserProb_parse_from_file(pl_parser, prob_file); probs_list = ParserProb_get_prob_list(pl_parser); if (NODE_LIST(NULL) != probs_list) { Compass_check_prob_list(tc, probs_list); } ParserProb_destroy(pl_parser); } /* ap_file */ if (NULL != ap_file) { ParserAp_ptr ap_parser = NULL; ap_parser = ParserAp_create(env); ParserAp_parse_from_file(ap_parser, ap_file); ap_list = ParserAp_get_ap_list(ap_parser); if (NODE_LIST(NULL) != ap_list) { Compass_check_ap_list(tc, ap_list); } ParserAp_destroy(ap_parser); } /* collects all required pieces */ state_mask = BddEnc_get_state_frozen_vars_mask_bdd(enc); input_mask = BddEnc_get_input_vars_mask_bdd(enc); next_state_mask = BddEnc_state_var_to_next_state_var(enc, state_mask); next_and_curr_state_mask = bdd_and(dd, state_mask, next_state_mask); { /* calculates the initial states */ bdd_ptr bdd_init = BddFsm_get_init(fsm); bdd_ptr bdd_sinvar = BddFsm_get_state_constraints(fsm); bdd_ptr bdd_iinvar = BddFsm_get_input_constraints(fsm); bdd_and_accumulate(dd, &bdd_init, bdd_sinvar); bdd_and_accumulate(dd, &bdd_init, bdd_iinvar); bdd_and_accumulate(dd, &bdd_init, state_mask); init_add = bdd_to_add(dd, bdd_init); bdd_free(dd, bdd_iinvar); bdd_free(dd, bdd_sinvar); bdd_free(dd, bdd_init); } { /* to control dynamic reordering */ dd_reorderingtype method; int dd_reord_status; /* Dynamic reordering during monolithic trans can improve performances */ dd_reord_status = dd_reordering_status(dd, &method); dd_autodyn_enable(dd, method); { /* calculates the transition relation */ bdd_ptr bdd_sinvar = BddFsm_get_state_constraints(fsm); bdd_ptr bdd_nsinvar = BddEnc_state_var_to_next_state_var(enc, bdd_sinvar); bdd_ptr bdd_iinvar = BddFsm_get_input_constraints(fsm); bdd_trans = BddFsm_get_monolithic_trans_bdd(fsm); bdd_and_accumulate(dd, &bdd_trans, bdd_sinvar); bdd_and_accumulate(dd, &bdd_trans, bdd_nsinvar); bdd_and_accumulate(dd, &bdd_trans, bdd_iinvar); bdd_and_accumulate(dd, &bdd_trans, next_and_curr_state_mask); bdd_and_accumulate(dd, &bdd_trans, input_mask); /* #define DEBUG_TRANS */ #ifdef DEBUG_TRANS FILE * p = stdout; // fopen("TRANS.txt", "w"); fprintf(p, "==================================================\n"); fprintf(p, "TRANS\n"); fprintf(p, "==================================================\n"); // print_trans(enc, bdd_trans, p); dd_printminterm(dd, bdd_trans); fprintf(p, "==================================================\n"); dd_printminterm(dd, input_mask); fprintf(p, "==================================================\n"); // fclose(p); #endif trans_add = bdd_to_add(dd, bdd_trans); bdd_free(dd, bdd_iinvar); bdd_free(dd, bdd_nsinvar); bdd_free(dd, bdd_sinvar); } /* Dynamic reordering is disabled after monolitic construction. Later it will be re-enabled if it was enable before entering this block */ dd_autodyn_disable(dd); /* probability and tau are optional */ if (probs_list != NODE_LIST(NULL)) { prob_add = Compass_process_prob_list(enc, probs_list, bdd_trans); } else prob_add = (add_ptr) NULL; bdd_free(dd, bdd_trans); if (tau != (Expr_ptr) NULL) { tau_add = BddEnc_expr_to_add(enc, tau, Nil); /* [RC]: This code was disable because it seems masks for input * var do not work */ /* mask_tau_add = BddEnc_apply_input_vars_mask_add(enc, tau_add); */ /* add_free(dd, tau_add); */ /* tau_add = mask_tau_add; */ } else tau_add = (add_ptr) NULL; if (NODE_LIST(NULL) != ap_list) { add_ptr expr_add, expr_add_mask; ListIter_ptr iter; ap_list_add = NodeList_create(); NODE_LIST_FOREACH(ap_list, iter) { node_ptr ap_el = (node_ptr)NodeList_get_elem_at(ap_list, iter); node_ptr lab = car(ap_el); node_ptr expr = cdr(ap_el); expr_add = BddEnc_expr_to_add(enc, expr, Nil); expr_add_mask = BddEnc_apply_state_frozen_vars_mask_add(enc, expr_add); NodeList_append(ap_list_add, cons(nodemgr, lab, (node_ptr)expr_add_mask)); add_free(dd, expr_add); /* The expr_add_mask will be freed later when the ap_list_add will be destroyed */ } }