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; }