Exemplo n.º 1
0
int RFG_Regions_stackPush( RFG_Regions* regions,
			   const uint32_t rid, const uint8_t decr,
			   RFG_RegionInfo** r_rinf )
{
  if( !regions || !regions->stack ) return 0;

  /* get region info by region id */

  *r_rinf = RFG_Regions_get( regions, rid );
  if( !(*r_rinf) ) return 0;

  /* enlarge call stack if necessary */

  if( regions->stack->pos+1 == (int32_t)regions->stack->size )
  {
    if( !stack_enlarge( regions->stack ) )
    {       
      fprintf( stderr, "RFG_Regions_stackPush(): Error: Could not enlarge stack size\n" );
      return 0;
    }
  }

  /* decrement call limit of region, if desired */

  if( decr && (*r_rinf)->callLimitCD > 0 ) 
    (*r_rinf)->callLimitCD--;

  /* push pointer new call stack entry to top of the call stack */

  regions->stack->
     entries[++regions->stack->pos].rinf = *r_rinf;
  regions->stack->
     entries[regions->stack->pos].climitbypush = (*r_rinf)->callLimitCD;

  return 1;
}
int RFG_Regions_stackPush( RFG_Regions* regions, uint32_t regionId,
                           RFG_RegionInfo** r_regionInfo,
                           RFG_CallPathInfo** r_cpathInfo,
                           uint8_t* r_wasApproved )
{
  RFG_RegionStackEntry* top;
  uint32_t* pos;

  if( !regions || !regions->stack )
    return 0;

  pos = &(regions->stack->pos);

  /* enlarge call stack, if necessary */

  if( (*pos)+1 == regions->stack->size )
  {
    if( !stack_enlarge( regions->stack ) )
    {
      fprintf( stderr,
        "RFG_Regions_stackPush(): Error: Could not enlarge stack size\n" );
      return 0;
    }
  }

  /* get pointer to the getting top of the call stack */
  top = &(regions->stack->entries[(*pos)+1]);

  /* update region info, if necessary */

  if( !top->region_info || top->region_info->regionId != regionId )
  {
    RFG_RegionInfoHN* region_info_hn =
      region_info_hash_get( regions->region_infos, regionId );
    if( !region_info_hn )
      return 0;

    top->region_info = &(region_info_hn->info);
  }

  /* increment call stack position */
  (*pos)++;

  /* update call-path info, if ... */

  if( /* ... we have any call-path filter rules, ... */
      regions->num_cpath_infos > 0 &&
      /* ... the new stack position does not exceed the max. number of regions
         in a call path, ... */
      *pos < RFG_FILTER_MAX_CPATH_SIZE+1 &&
      /* ... and the current call-path isn't equal to the previous one */
      ( regions->stack->cpath_region_ids[*pos] != regionId ||
        regions->stack->cpath_last_equal_pos < *pos ) )
  {
    RFG_CallPathInfoHN* cpath_info_hn;

    /* update last stack position where the current call path is equal to
       the previous one */
    regions->stack->cpath_last_equal_pos = *pos;

    /* generate hash value of current call path */
    regions->stack->cpath_hashes[*pos] =
      vt_hashtriple( regionId, 0, 0, regions->stack->cpath_hashes[(*pos)-1] );
    /* add region id to array */
    regions->stack->cpath_region_ids[*pos] = regionId;

    /* search matching call-path info in hash table */

    cpath_info_hn =
      cpath_info_hash_get( regions->cpath_infos,
        regions->stack->cpath_hashes[*pos], *pos,
        regions->stack->cpath_region_ids+1 );
    if( cpath_info_hn )
      top->cpath_info = &(cpath_info_hn->info);
    else
      top->cpath_info = NULL;
  }

  /* reject or approve the region enter event ... */

  /* ... either by the call-path filter rules (if available) */
  if( top->cpath_info )
  {
    if( /*regions->recursive_filter_active_cnt > 0 ||*/
        top->cpath_info->callLimitCD == 0 )
    {
      top->was_approved = 0;

      /* call-paths are always filtered recursively; increment recursive
         filter activation counter */
      /*regions->recursive_filter_active_cnt++;*/
    }
    else
    {
      top->was_approved = 1;

      /* decrement call-path's and region's call limit */

      if( top->cpath_info->callLimitCD > 0 )
        top->cpath_info->callLimitCD--;
      if( top->region_info->callLimitCD > 0 )
        top->region_info->callLimitCD--;
    }
  }
  /* ... or by the region filter rules */
  else
  {
    if( /*regions->recursive_filter_active_cnt > 0 ||*/
        top->region_info->callLimitCD == 0 ||
        *pos < top->region_info->stackBounds[0] ||
        *pos > top->region_info->stackBounds[1] )
    {
      top->was_approved = 0;

      /* increment recursive filter activation counter, if region shall be
         filtered recursively */
      /*if( (top->region_info->flags & RFG_FILTER_FLAG_RECURSIVE) != 0 )
        regions->recursive_filter_active_cnt++;*/
    }
    else
    {
      top->was_approved = 1;

      /* decrement region's call limit */
      if( top->region_info->callLimitCD > 0 )
        top->region_info->callLimitCD--;
    }
  }

  if( r_regionInfo )
    *r_regionInfo = top->region_info;
  if( r_cpathInfo )
    *r_cpathInfo = top->cpath_info;
  if( r_wasApproved )
    *r_wasApproved = top->was_approved;

  return 1;
}
void stack_push(Stack *stack, struct TreeNode *node) {
    if(stack->top >= stack->size)
        stack_enlarge(stack);
    stack->base[stack->top++] = node;
}