1 /*---------------------------------------------------------------------------
2  * Eval Cost functions.
3  *
4  *---------------------------------------------------------------------------
5  */
6 
7 #ifndef I_EVAL_COST__
8 #define I_EVAL_COST__
9 
10 #include "driver.h"
11 
12 #include "interpret.h"
13 
14 /*-------------------------------------------------------------------------*/
15 static INLINE Bool
add_eval_cost_n(int32 added_cost,uint repetitions)16 add_eval_cost_n (int32 added_cost, uint repetitions)
17 
18 /* Increase the evaluation cost by <added_cost>*<repetitions>. Return TRUE if
19  * this would exceed max_eval_cost, return FALSE if not.
20  *
21  * Passing <repetitions> explicitely guards against situations where
22  * <added_cost>*<repetitions> itself would overflow.
23  *
24  * To safeguard the driver against ridiculous executions, the actual eval_cost
25  * is capped at max_eval_cost+1.
26  */
27 
28 {
29     if (repetitions == 0)
30         return MY_FALSE;
31 
32     if (max_eval_cost)
33     {
34         /* Test the evaluation cost against the limit.
35          * eval_cost < 0 signify a wrap-around - unlikely, but with these crazy
36          * wizards everything is possible.
37          */
38         if (eval_cost >= max_eval_cost || eval_cost < 0)
39             return MY_TRUE;
40 
41         if (max_eval_cost - eval_cost < added_cost
42          || (int32)((max_eval_cost - eval_cost) / repetitions) < added_cost
43            )
44         {
45             total_evalcost += max_eval_cost - eval_cost + 1;
46             eval_cost = max_eval_cost+1;
47             return MY_TRUE;
48         }
49     }
50 
51     eval_cost += added_cost * repetitions;
52     total_evalcost += added_cost * repetitions;
53 
54     return MY_FALSE;
55 } /* add_eval_cost_n() */
56 
57 /*-------------------------------------------------------------------------*/
58 
59 /* --- Macros --- */
60 
61 /* Increase the eval cost for a non-repetitive action.
62  */
63 #define add_eval_cost(cost) add_eval_cost_n(cost, 1)
64 
65 /* Reset the evaluation cost/time counter.
66  */
67 #define CLEAR_EVAL_COST (assigned_eval_cost = eval_cost = 0)
68 
69 /* Check if the current evaluation took too long
70  */
71 #define EVALUATION_TOO_LONG() \
72     (max_eval_cost && (eval_cost >= max_eval_cost || eval_cost < 0))
73 
74 /* Return the amount of remaining evaluation costs, or MAX_INT if there
75  * is no real maximum.
76  */
77 #define GET_REMAINING_EVAL_COST() \
78     ( max_eval_cost ? ((eval_cost >= max_eval_cost || eval_cost < 0) ? 0 : (max_eval_cost - eval_cost)) : INT32_MAX)
79 
80 /***************************************************************************/
81 
82 #endif /* I_EVAL_COST__ */
83