From 9a7a89468fc9d895c2e210f6172158ac1504d8c5 Mon Sep 17 00:00:00 2001 From: bdemsky Date: Wed, 14 Dec 2016 17:38:02 -0800 Subject: [PATCH] Document interface --- include/libinterface.h | 126 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 113 insertions(+), 13 deletions(-) diff --git a/include/libinterface.h b/include/libinterface.h index e569ba1..2be9040 100644 --- a/include/libinterface.h +++ b/include/libinterface.h @@ -18,52 +18,152 @@ extern "C" { #define MCID_FIRST ((MCID)1) #define MC2_OFFSET(x, y) (uintptr_t)(&((x)(0))->y) + + /** Stores N bits of val to the location given by addr. */ void store_8(void *addr, uint8_t val); void store_16(void *addr, uint16_t val); void store_32(void *addr, uint32_t val); void store_64(void *addr, uint64_t val); + /** Loads N bits from the location given by addr. */ + uint8_t load_8(const void *addr); uint16_t load_16(const void *addr); uint32_t load_32(const void *addr); uint64_t load_64(const void *addr); - + + /** Atomic operation enumeration for RMW operations. */ + enum atomicop { ADD, - CAS, - EXC + CAS /* Compare and swap */, + EXC /* Exchange */ }; + /** Performs an atomic N bit RMW (read-modify-write) operation as + specified by op to the address specified by addr. + For CAS, oldval gives the value to be compared against while + valarg is the value to be written. + For EXC, valarg is the value to be written and oldval is ignored. + For ADD, valarg is the value to be added and oldval is ignored. */ + uint8_t rmw_8(enum atomicop op, void *addr, uint8_t oldval, uint8_t valarg); uint16_t rmw_16(enum atomicop op, void *addr, uint16_t oldval, uint16_t valarg); uint32_t rmw_32(enum atomicop op, void *addr, uint32_t oldval, uint32_t valarg); uint64_t rmw_64(enum atomicop op, void *addr, uint64_t oldval, uint64_t valarg); - MCID MC2_nextRMW(MCID addr, MCID oldval, MCID valarg); + + /** Specifies the sources of the arguments for the following + RMW/Load/Store operation. All RMW/Load/Store operations must be + immediately preceded by a + MC2_nextRMW/MC2_nextOpLoad/MC2_nextOpStore call or one of the + offset calls specified in the next section below. The + MC2_nextRMW and MC2_nextOpLoad return a MCID for the value + read.*/ + + MCID MC2_nextRMW(MCID addr, MCID oldval, MCID valarg); MCID MC2_nextOpLoad(MCID addr); void MC2_nextOpStore(MCID addr, MCID value); - + + /** Specifies the sources of the arguments for the following + RMW/Load/Store operation that includes a fixed offset from the + address specified by addr. + For example, load_8(x.f) could be be instrumented with a + MC2_nextOpLoadOffset(_m_x, offset of f in structure). */ + MCID MC2_nextRMWOffset(MCID addr, uintptr_t offset, MCID oldval, MCID valarg); - MCID MC2_nextOpLoadOffset(MCID addr, uintptr_t offset); void MC2_nextOpStoreOffset(MCID addr, uintptr_t offset, MCID value); - MCID MC2_branchUsesID(MCID condition, int direction, int num_directions, bool anyvalue); - void MC2_nextOpThrd_create(MCID startfunc, MCID param); + + /** Specifies that we just took the direction "direction" of a + conditional branch with "num_directions" possible directions. + The MCIDcondition gives the MCID for the variable that we + conditionally branched on. The boolean anyvalue is set if any + non-zero value means that the branch will simply take direction + 1. + */ + + MCID MC2_branchUsesID(MCID condition, int direction, int num_directions, bool anyvalue); + + /** Currently not used. Should be implemented later. */ + void MC2_nextOpThrd_create(MCID startfunc, MCID param); void MC2_nextOpThrd_join(MCID jointhrd); + /** Specifies that we have hit the merge point of a conditional + branch. The MCID branchid specifies the conditional branch that + just merged. */ + + void MC2_merge(MCID branchid); - MCID MC2_function(unsigned int num_args, int numbytesretval, uint64_t val, ...); - MCID MC2_function_id(unsigned int id, unsigned int num_args, int numbytesretval, uint64_t val, ...); + + /** Specifies a uninterpreted function with num_args parameters, a + return value of numbytesretval bytes that returned the actual + value val. The MCIDs for all inputs are then specified + afterwards. The return MCID is MCID corresponding to the output + of the uninterpreted function. Uninterpreted functions + specified via this annotation are unique to the given dynamic + instance. For example, if there is an unintepreted function + call in a loop annotated by MC2_function, results from the first + iteration will NOT be aggregated with results from later + iterations. + */ + + MCID MC2_function(unsigned int num_args, int numbytesretval, uint64_t val, ...); + + /** Arguments are the same as MC2_function, but results are + aggregated for all instances with the same id. The id must be + greater than 0. This is generally useful for functions where all + inputs are specified via MCIDs. */ + + MCID MC2_function_id(unsigned int id, unsigned int num_args, int numbytesretval, uint64_t val, ...); + + /** MC2_equals implements equality comparison. It takes in two + arguments (val1 and val2) and the corresponding MCIDs (op1 and + op2). It returns the result val1==val2. The MCID for the + return value is returned via the pointer *retval. */ + uint64_t MC2_equals(MCID op1, uint64_t val1, MCID op2, uint64_t val2, MCID *retval); - MCID MC2_phi(MCID input); + /** MC2_phi specifies a phi function. The MCID input is the input + identifier and the returned MCID is the output of the phi + function. This is generally useful for instrumenting cases of the following form: + if (x) { + y=0; + } else { + y=1; + } + This example would require a MC2_phi at the merge point. + */ + + MCID MC2_phi(MCID input); + + /** MC2_loop_phi is a phi function for loops. This is useful for code like the following: + while() { + x=x+1; + if (....) + break; + } + return x; + This example would require a MC2_loop_phi after the MC2_exitLoop annotation for the loop. + */ + MCID MC2_loop_phi(MCID input); + /** MC2_yield is a yield operation. */ void MC2_yield(); + + /** MC2_fence specifies that the next operation is a memory fence. */ void MC2_fence(); - void MC2_enterLoop(); - void MC2_exitLoop(); + + /** MC2_enterLoop specifies that the next statement is a loop. */ + void MC2_enterLoop(); + + /** MC2_exitLoop specifies exit of a loop. */ + void MC2_exitLoop(); + + /** MC2_loopIterator specifies the next iteration of a loop. This is + currently not strictly necessary to use. */ void MC2_loopIterate(); #ifdef __cplusplus } -- 2.34.1