1 /** @file libinterface.h
2 * @brief Interface to check normal memory operations for data races.
5 #ifndef __LIBINTERFACE_H__
6 #define __LIBINTERFACE_H__
13 typedef unsigned int MCID;
14 #define MC2_PTR_LENGTH sizeof(void *)
16 #define MCID_NODEP ((MCID)0)
17 #define MCID_INIT ((MCID)0)
18 #define MCID_FIRST ((MCID)1)
20 #define MC2_OFFSET(x, y) (uintptr_t)(&((x)(0))->y)
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);
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);
34 /** Atomic operation enumeration for RMW operations. */
38 CAS /* Compare and swap */,
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. */
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);
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
63 MCID MC2_nextRMW(MCID addr, MCID oldval, MCID valarg);
64 MCID MC2_nextOpLoad(MCID addr);
65 void MC2_nextOpStore(MCID addr, MCID value);
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). */
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);
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
85 MCID MC2_branchUsesID(MCID condition, int direction, int num_directions, bool anyvalue);
87 /** Currently not used. Should be implemented later. */
88 void MC2_nextOpThrd_create(MCID startfunc, MCID param);
89 void MC2_nextOpThrd_join(MCID jointhrd);
91 /** Specifies that we have hit the merge point of a conditional
92 branch. The MCID branchid specifies the conditional branch that
94 void MC2_merge(MCID branchid);
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
108 MCID MC2_function(unsigned int num_args, int numbytesretval, uint64_t val, ...);
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. */
115 MCID MC2_function_id(unsigned int id, unsigned int num_args, int numbytesretval, uint64_t val, ...);
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. */
122 uint64_t MC2_equals(MCID op1, uint64_t val1, MCID op2, uint64_t val2, MCID *retval);
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:
132 This example would require a MC2_phi at the merge point.
135 MCID MC2_phi(MCID input);
137 /** MC2_loop_phi is a phi function for loops. This is useful for code like the following:
144 This example would require a MC2_loop_phi after the MC2_exitLoop annotation for the loop.
147 MCID MC2_loop_phi(MCID input);
149 /** MC2_yield is a yield operation. */
152 /** MC2_fence specifies that the next operation is a memory fence. */
155 /** MC2_enterLoop specifies that the next statement is a loop. */
156 void MC2_enterLoop();
158 /** MC2_exitLoop specifies exit of a loop. */
161 /** MC2_loopIterator specifies the next iteration of a loop. This is
162 currently not strictly necessary to use. */
163 void MC2_loopIterate();
168 #endif /* __LIBINTERFACE_H__ */