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