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

}
Example #3
0
/*************************************************************
* 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() */
Example #4
0
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 */
      }
    }