whitespace -> use tabs
[satcheck.git] / include / libinterface.h
1 /** @file libinterface.h
2  *  @brief Interface to check normal memory operations for data races.
3  */
4
5 #ifndef __LIBINTERFACE_H__
6 #define __LIBINTERFACE_H__
7
8 #include <stdint.h>
9
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13         typedef unsigned int MCID;
14 #define MC2_PTR_LENGTH sizeof(void *)
15
16 #define MCID_NODEP ((MCID)0)
17 #define MCID_INIT ((MCID)0)
18 #define MCID_FIRST ((MCID)1)
19
20 #define MC2_OFFSET(x, y) (uintptr_t)(&((x)(0))->y)
21
22         /** Stores N bits of val to the location given by addr. */
23         void store_8(void *addr, uint8_t val);
24         void store_16(void *addr, uint16_t val);
25         void store_32(void *addr, uint32_t val);
26         void store_64(void *addr, uint64_t val);
27
28         /** Loads N bits from the location given by addr. */
29         uint8_t load_8(const void *addr);
30         uint16_t load_16(const void *addr);
31         uint32_t load_32(const void *addr);
32         uint64_t load_64(const void *addr);
33
34         /** Atomic operation enumeration for RMW operations. */
35         
36         enum atomicop {
37                 ADD,
38                 CAS /* Compare and swap */,
39                 EXC /* Exchange */
40         };
41
42         /** Performs an atomic N bit RMW (read-modify-write) operation as
43                         specified by op to the address specified by addr.
44                         For CAS, oldval gives the value to be compared against while
45                         valarg is the value to be written.
46                         For EXC, valarg is the value to be written and oldval is ignored.
47                         For ADD, valarg is the value to be added and oldval is ignored. */
48         
49         uint8_t rmw_8(enum atomicop op, void *addr, uint8_t oldval, uint8_t valarg);
50         uint16_t rmw_16(enum atomicop op, void *addr, uint16_t oldval, uint16_t valarg);
51         uint32_t rmw_32(enum atomicop op, void *addr, uint32_t oldval, uint32_t valarg);
52         uint64_t rmw_64(enum atomicop op, void *addr, uint64_t oldval, uint64_t valarg);
53
54
55         /** Specifies the sources of the arguments for the following
56                         RMW/Load/Store operation. All RMW/Load/Store operations must be
57                         immediately preceded by a
58                         MC2_nextRMW/MC2_nextOpLoad/MC2_nextOpStore call or one of the
59                         offset calls specified in the next section below. The
60                         MC2_nextRMW and MC2_nextOpLoad return a MCID for the value
61                         read.*/
62         
63         MCID MC2_nextRMW(MCID addr, MCID oldval, MCID valarg);
64         MCID MC2_nextOpLoad(MCID addr);
65         void MC2_nextOpStore(MCID addr, MCID value);
66         
67         /** Specifies the sources of the arguments for the following
68                         RMW/Load/Store operation that includes a fixed offset from the
69                         address specified by addr. 
70                         For example, load_8(x.f) could be be instrumented with a
71                         MC2_nextOpLoadOffset(_m_x, offset of f in structure). */
72                 
73         MCID MC2_nextRMWOffset(MCID addr, uintptr_t offset, MCID oldval, MCID valarg);
74         MCID MC2_nextOpLoadOffset(MCID addr, uintptr_t offset);
75         void MC2_nextOpStoreOffset(MCID addr, uintptr_t offset, MCID value);
76
77         /** Specifies that we just took the direction "direction" of a
78                         conditional branch with "num_directions" possible directions.
79                         The MCIDcondition gives the MCID for the variable that we
80                         conditionally branched on. The boolean anyvalue is set if any
81                         non-zero value means that the branch will simply take direction
82                         1.
83         */
84
85         MCID MC2_branchUsesID(MCID condition, int direction, int num_directions, bool anyvalue);
86
87         /** Currently not used. Should be implemented later. */
88         void MC2_nextOpThrd_create(MCID startfunc, MCID param);
89         void MC2_nextOpThrd_join(MCID jointhrd);
90
91         /** Specifies that we have hit the merge point of a conditional
92                         branch. The MCID branchid specifies the conditional branch that
93                         just merged. */
94         void MC2_merge(MCID branchid);
95
96         /** Specifies a uninterpreted function with num_args parameters, a
97                         return value of numbytesretval bytes that returned the actual
98                         value val. The MCIDs for all inputs are then specified
99                         afterwards. The return MCID is MCID corresponding to the output
100                         of the uninterpreted function. Uninterpreted functions
101                         specified via this annotation are unique to the given dynamic
102                         instance. For example, if there is an unintepreted function
103                         call in a loop annotated by MC2_function, results from the first
104                         iteration will NOT be aggregated with results from later
105                         iterations.
106         */
107
108         MCID MC2_function(unsigned int num_args, int numbytesretval, uint64_t val, ...);
109
110         /** Arguments are the same as MC2_function, but results are
111                         aggregated for all instances with the same id. The id must be
112                         greater than 0. This is generally useful for functions where all
113                         inputs are specified via MCIDs. */
114
115         MCID MC2_function_id(unsigned int id, unsigned int num_args, int numbytesretval, uint64_t val, ...);
116
117         /** MC2_equals implements equality comparison. It takes in two
118                         arguments (val1 and val2) and the corresponding MCIDs (op1 and
119                         op2). It returns the result val1==val2. The MCID for the
120                         return value is returned via the pointer *retval. */
121
122         uint64_t MC2_equals(MCID op1, uint64_t val1, MCID op2, uint64_t val2, MCID *retval);
123         
124         /** MC2_phi specifies a phi function. The MCID input is the input
125                         identifier and the returned MCID is the output of the phi
126                         function. This is generally useful for instrumenting cases of the following form:
127                         if (x) {
128                                 y=0;
129                         } else {
130                                 y=1;
131                         }
132                         This example would require a MC2_phi at the merge point.
133         */
134
135         MCID MC2_phi(MCID input);
136
137         /** MC2_loop_phi is a phi function for loops. This is useful for code like the following:
138                         while() {
139                                 x=x+1;
140                                 if (....)
141                                         break;
142                         }
143                         return x;
144                         This example would require a MC2_loop_phi after the MC2_exitLoop annotation for the loop.
145          */
146
147         MCID MC2_loop_phi(MCID input);
148
149         /** MC2_yield is a yield operation. */
150         void MC2_yield();
151         
152         /** MC2_fence specifies that the next operation is a memory fence. */
153         void MC2_fence();
154
155         /** MC2_enterLoop specifies that the next statement is a loop. */
156         void MC2_enterLoop();
157
158         /** MC2_exitLoop specifies exit of a loop. */
159         void MC2_exitLoop();
160
161         /** MC2_loopIterator specifies the next iteration of a loop. This is
162                         currently not strictly necessary to use. */
163         void MC2_loopIterate();
164 #ifdef __cplusplus
165 }
166 #endif
167
168 #endif /* __LIBINTERFACE_H__ */