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. */
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);
29 /** Loads N bits from the location given by addr. */
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);
36 /** Atomic operation enumeration for RMW operations. */
40 CAS /* Compare and swap */,
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. */
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);
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
65 MCID MC2_nextRMW(MCID addr, MCID oldval, MCID valarg);
66 MCID MC2_nextOpLoad(MCID addr);
67 void MC2_nextOpStore(MCID addr, MCID value);
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). */
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);
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
87 MCID MC2_branchUsesID(MCID condition, int direction, int num_directions, bool anyvalue);
89 /** Currently not used. Should be implemented later. */
90 void MC2_nextOpThrd_create(MCID startfunc, MCID param);
91 void MC2_nextOpThrd_join(MCID jointhrd);
93 /** Specifies that we have hit the merge point of a conditional
94 branch. The MCID branchid specifies the conditional branch that
98 void MC2_merge(MCID branchid);
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
112 MCID MC2_function(unsigned int num_args, int numbytesretval, uint64_t val, ...);
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. */
119 MCID MC2_function_id(unsigned int id, unsigned int num_args, int numbytesretval, uint64_t val, ...);
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. */
126 uint64_t MC2_equals(MCID op1, uint64_t val1, MCID op2, uint64_t val2, MCID *retval);
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:
136 This example would require a MC2_phi at the merge point.
139 MCID MC2_phi(MCID input);
141 /** MC2_loop_phi is a phi function for loops. This is useful for code like the following:
148 This example would require a MC2_loop_phi after the MC2_exitLoop annotation for the loop.
151 MCID MC2_loop_phi(MCID input);
153 /** MC2_yield is a yield operation. */
156 /** MC2_fence specifies that the next operation is a memory fence. */
159 /** MC2_enterLoop specifies that the next statement is a loop. */
160 void MC2_enterLoop();
162 /** MC2_exitLoop specifies exit of a loop. */
165 /** MC2_loopIterator specifies the next iteration of a loop. This is
166 currently not strictly necessary to use. */
167 void MC2_loopIterate();
172 #endif /* __LIBINTERFACE_H__ */