TM Workloads communicate with the simulator through a set of magic calls (special no-op instructions) The interface between workloads and the LogTM simulator is defined in $GEMS/microbenchmarks/transactional/common/transaction.h

#define NEW_RUBY_MAGIC_CALL( service )                      \
  __asm__ __volatile__                                      \
    ( "sethi %1, %%g0  !magic service %2\n\t"               \
          : /* no outputs */                                \
      : "r" (0), "i" (service), "i" (service)         \
          : "l0", "memory" /* clobber register */                     \
        );

#define SET_LOG_BASE NEW_RUBY_MAGIC_CALL(8)
#define SET_HANDLER_ADDRESS NEW_RUBY_MAGIC_CALL(9)
#define RELEASE_ISOLATION NEW_RUBY_MAGIC_CALL(10)
#define HANDLER_RESTART NEW_RUBY_MAGIC_CALL(11)
#define HANDLER_CONTINUE NEW_RUBY_MAGIC_CALL(28)

#define BEGIN_CLOSED_TRANSACTION(id)  NEW_RUBY_MAGIC_CALL(id + 1024)
#define COMMIT_CLOSED_TRANSACTION(id) NEW_RUBY_MAGIC_CALL(id + 2048)
#define BEGIN_OPEN_TRANSACTION(id)    NEW_RUBY_MAGIC_CALL(id + 3072)
#define COMMIT_OPEN_TRANSACTION(id)   NEW_RUBY_MAGIC_CALL(id + 4096)

#define ABORT_TRANSACTION(id)         NEW_RUBY_MAGIC_CALL(id + 6144)
...

The software component of LogTM is implemented in $GEMS/microbenchmarks/transactional/common/transaction.c

To setup a TM workload

init_transaction_state(int num_threads)

set_transaction_registers(int threadID)

A generic TM workload would look like:

int main() {
   ...
   init_transaction_state(num_threads)
   ...
   // CREATE_THREADS
   // WAIT FOR THREADS TO FINISH
}

void slaveFunction() {
   ...
   tm_bind_to_cabinet(myid) // BIND THREADS TO PROCESSORS TO AVOID THREAD MIGRATION
   Barrier_breaking(...)    // SYNCHRONIZE THREADS AND START SIMULATION WHEN ALL THREADS HAVE REACHED THE BARRIER

   set_transaction_registers(myid) // SET LOGTM SPECIFIC REGISTERS IN HARDWARE

   ... // DO SOME PARALLEL WORK

   Barrier_breaking(...)   // SYNCHRONIZE THREADS AND END SIMULATION WHEN ALL THREADS HAVE REACHED THE BARRIER
}

void Foo() {
   ...
   BEGIN_TRANSACTION(7)
   ...                     // CRITICAL SECTION
   COMMIT_TRANSACTION(7)
}

A set of sample TM programs can be found at $GEMS/microbenchmarks/transactional/

***IMPORTANT***: After compiling your transactional program, make sure the offset to the software abort handler is correct. This offset is HARDCODED in the GEMS release and may need to be changed depending on the compiler and/or compiler flags used. The offset is specified by a statement inside set_transaction_registers():

To get the offset for your binary, run gdb on your compiled binary and disassemble transaction_manager_stub():

(gdb) disassemble transaction_manager_stub
Dump of assembler code for function transaction_manager_stub:
0x0001e004 <transaction_manager_stub+0>:        save  %sp, -112, %sp
0x0001e008 <transaction_manager_stub+4>:        cmp  %i0, 0
0x0001e00c <transaction_manager_stub+8>:        bne  0x1e04c <transaction_manager_stub+72>
0x0001e010 <transaction_manager_stub+12>:       clr  %o5
0x0001e014 <transaction_manager_stub+16>:       sethi  %hi(0x1800), %g0 <============ This is the BEGIN_ESCAPE magic instruction, and the reason for the offset 16

Then make sure the offset set in set_transaction_registers() matches that found from above:

void *handler_address = &transaction_manager_stub + 16;    //16 is the offset to the BEGIN_ESCAPE instruction in transaction_manager_stub()

TM_Workload_Setup (last edited 2008-08-01 16:15:14 by LukeYen)