diff --git a/backends/norec/Defines.common.mk b/backends/norec/Defines.common.mk index 193874ce7c0d39a358d633050c51975eed90c86c..6e54f22b36357f3dbff0406580b88d4b6a92963e 100644 --- a/backends/norec/Defines.common.mk +++ b/backends/norec/Defines.common.mk @@ -1,7 +1,7 @@ CC := gcc CFLAGS += -g -Wall -pthread CFLAGS += -O3 -CFLAGS += -I$(LIB) -I../rapl-power/ +CFLAGS += -I$(LIB) CPP := g++ CPPFLAGS += $(CFLAGS) LD := g++ diff --git a/backends/norec/Makefile b/backends/norec/Makefile index 4e52694cc9b614b37951662eb2a3dc3b1c267a88..e0cbc1a2c3ee9870402dac97cc8388bc391a0a0b 100644 --- a/backends/norec/Makefile +++ b/backends/norec/Makefile @@ -1,7 +1,7 @@ CFLAGS += -w -DSTM -I$(STM) CPPFLAGS := $(CFLAGS) LDFLAGS += -L$(STM) -LIBS += -lnorec -L../rapl-power -lrapl +LIBS += -lnorec .PHONY: default default: $(PROG) diff --git a/backends/norec/thread.c b/backends/norec/thread.c index 383169f5dbddf30a7f18a1b80ac14c3346b0e81c..453352dd6e84ac97621e89572ac28bb3c363f5cc 100644 --- a/backends/norec/thread.c +++ b/backends/norec/thread.c @@ -7,7 +7,7 @@ #include <sched.h> #include "thread.h" #include "types.h" -#include "rapl.h" +//#include "rapl.h" static THREAD_LOCAL_T global_threadId; static long global_numThread = 1; @@ -38,7 +38,7 @@ static void threadWait (void* argPtr) global_funcPtr(global_argPtr); THREAD_BARRIER(global_barrierPtr, threadId); /* wait for end parallel */ if (threadId == 0) { - endEnergy(); + //endEnergy(); break; } } @@ -71,7 +71,7 @@ void thread_startup (long numThread) global_threads = (THREAD_T*)malloc(numThread * sizeof(THREAD_T)); assert(global_threads); - startEnergy(); + //startEnergy(); /* Set up pool */ THREAD_ATTR_INIT(global_threadAttr); diff --git a/build.sh b/build.sh index 67dc7f657155b87d6eab5ab87ba2de72beac188e..2b43f71c8a0082c12862a897453db63e2e10850f 100644 --- a/build.sh +++ b/build.sh @@ -1,7 +1,7 @@ #!/bin/sh -FOLDERS="genome intruder kmeans labyrinth ssca2 vacation yada redblacktree hashmap" - +FOLDERS="manual_example" +#genome intruder kmeans labyrinth ssca2 vacation yada redblacktree hashmap bash clean.sh echo "Configuring $1" diff --git a/manual_example/Defines.common.mk b/manual_example/Defines.common.mk new file mode 100644 index 0000000000000000000000000000000000000000..4b790c813dd53f0f9c5f985260acb1170a824798 --- /dev/null +++ b/manual_example/Defines.common.mk @@ -0,0 +1,17 @@ +LIBS += -lm + +PROG := shared_memory_example + +SRCS += \ + shared_memory_example.c \ + $(LIB)/list.c \ + $(LIB)/mt19937ar.c \ + $(LIB)/pair.c \ + $(LIB)/queue.c \ + $(LIB)/random.c \ + $(LIB)/thread.c \ + $(LIB)/vector.c \ +# +OBJS := ${SRCS:.c=.o} + +CFLAGS += -DUSE_EARLY_RELEASE diff --git a/manual_example/Makefile b/manual_example/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..3b67385120df9a8ee82da25c2e81f854c39f507f --- /dev/null +++ b/manual_example/Makefile @@ -0,0 +1,4 @@ +LIBS = -lpmemobj +include ../common/Defines.common.mk +include ./Defines.common.mk +include ../common/Makefile diff --git a/manual_example/shared_memory_example b/manual_example/shared_memory_example new file mode 100755 index 0000000000000000000000000000000000000000..25d85b9dbb0f52e0a08b34970c54922db275e7cd Binary files /dev/null and b/manual_example/shared_memory_example differ diff --git a/manual_example/shared_memory_example.c b/manual_example/shared_memory_example.c new file mode 100644 index 0000000000000000000000000000000000000000..10f2df24f3c667dd96a57df84c7d1cd853169932 --- /dev/null +++ b/manual_example/shared_memory_example.c @@ -0,0 +1,133 @@ +#include <stdio.h> +#include <stdlib.h> +#include <libpmemobj/base.h> +#include <unistd.h> +#include <stdbool.h> +#include <libpmemobj/pool_base.h> +#include <libpmemobj/types.h> +#include "list.h" +#include "thread.h" +#include <libpmemobj/tx_base.h> + +#define shared_memory_size 10000 + +struct thread_context{ + char buff[shared_memory_size]; +}; + +struct dram_thread_context{ + PMEMobjpool *pop; + struct thread_context *th; +}; + +struct pmem_obj_root{ + struct thread_context th; +}; + +static void +log_stages(PMEMobjpool *pop_local, enum pobj_tx_stage stage, void *arg) +{ + /* Commenting this out because this is not required during normal execution. */ + /* dr_fprintf(STDERR, "cb stage: ", desc[stage], " "); */ +} + +bool file_exists(const char *path){ + return access(path, F_OK) != 0; +} + +void *p_region(void *context){ + struct dram_thread_context *dramThreadContext = context; + struct thread_context *th = dramThreadContext->th; + + int *attempt = malloc(sizeof(int)); + *attempt = 0; + + /* --------------------------- */ + //TM_THREAD_ENTER(); + Thread *Self = TxNewThread(); + TxInitThread(Self, thread_getId()); + /* --------------------------- */ + + /* -------- */ + //TM_BEGIN(); + + do { \ + STM_JMPBUF_T STM_JMPBUF; \ + sigsetjmp(STM_JMPBUF, 1); \ + TxStart(STM_SELF, &STM_JMPBUF); \ + } while (0); + /* -----------*/ + + //ABORTED TRANSACTION JUMPS TO THIS POINT + + char randomletter = 'A' + (random() % 26); + for (int i = 0; i < shared_memory_size; i++) { + TM_SHARED_WRITE(th->buff[i], randomletter); + } + + /* --------------------------- */ + //TM_END(); + TxCommit(Self, dramThreadContext->pop); + /* --------------------------- */ + //Changes are visible here + printf("Post TM_END written to shared_write: %c Current local value: %c\n", randomletter, th->buff[0]); + TM_THREAD_EXIT(); + return 0; +} + + +PMEMobjpool *mmap_pmem_object_pool(PMEMobjpool *pop){ + char *path_to_pmem = "/mnt/dax/test_outputs/norec_with_pmem"; + if (file_exists((path_to_pmem)) != 0) { + if ((pop = pmemobj_create(path_to_pmem, POBJ_LAYOUT_NAME(list),10000000, 0666)) == NULL) + perror("failed to create pool\n"); + } else { + if ((pop = pmemobj_open(path_to_pmem, POBJ_LAYOUT_NAME(list))) == NULL) { + perror("failed to open pool\n"); + } + } + return pop; +} + +struct thread_context* initialise_thread_context_on_persistent_memory(PMEMobjpool *pop){ + PMEMoid pool_root = pmemobj_root(pop, sizeof(struct pmem_obj_root)); + struct pmem_obj_root *rootp = pmemobj_direct(pool_root); + return &rootp->th; +} + +MAIN(argc, argv) +{ + PMEMobjpool *pop = NULL; + pop = mmap_pmem_object_pool(pop); + struct thread_context *th = initialise_thread_context_on_persistent_memory(pop); + struct dram_thread_context *dramThreadContext = malloc(sizeof (struct dram_thread_context)); + dramThreadContext->pop = pop; + dramThreadContext->th = th; + + printf("Initial content:\n"); + for(int i=0; i< shared_memory_size; i++ ){ + printf("%c", th->buff[i]); + } + puts("\n"); + + GOTO_REAL(); + int arr_len = 30; + TM_STARTUP(arr_len); + pthread_t thread_array[arr_len]; + + for (int i = 0; i < arr_len; i++) { + pthread_create(&thread_array[i], NULL, p_region, dramThreadContext); + } + + for (int i = 0; i < arr_len; i++) { + pthread_join(thread_array[i], NULL); + } + + printf("Result:\n"); + for(int i=0; i< shared_memory_size; i++ ){ + printf("%c", th->buff[i]); + } + printf("\n"); + TM_SHUTDOWN(); + MAIN_RETURN(0); +} \ No newline at end of file diff --git a/norec/Makefile b/norec/Makefile index 8c0a1e2efbb5f6575eb66c741f75fd907186a69a..78ed9960f66848e3d83374885a9687b4b4b02737 100644 --- a/norec/Makefile +++ b/norec/Makefile @@ -15,6 +15,7 @@ CFLAGS := -g -w -O3 LD := gcc LIBNOREC := libnorec.a +LIBS = -lpmemobj SRCS := \ norec.c \ diff --git a/norec/norec.c b/norec/norec.c index b4797047b0b793e3b2efbda2b9805dc2a3cac4f6..ca13de005168895f3b0ef99de4a0dcf063e593af 100644 --- a/norec/norec.c +++ b/norec/norec.c @@ -5,6 +5,8 @@ #include <assert.h> #include <pthread.h> #include <signal.h> +#include <libpmemobj/base.h> +#include <libpmemobj/tx_base.h> #include "platform.h" #include "norec.h" #include "util.h" @@ -174,14 +176,41 @@ ExtendList (AVPair* tail) return e; } +static void +log_stages(PMEMobjpool *pop_local, enum pobj_tx_stage stage, void *arg) +{ + /* Commenting this out because this is not required during normal execution. */ + /* dr_fprintf(STDERR, "cb stage: ", desc[stage], " "); */ +} + + __INLINE__ void -WriteBackForward (Log* k) +WriteBackForward (Log* k, PMEMobjpool *pop) { + //printf("writeback point\n"); AVPair* e; AVPair* End = k->put; + + //Add to the undo log + printf("Starting a transaction\n"); + /* Sometimes breaks here */ + pmemobj_tx_begin(pop, NULL, TX_PARAM_CB, log_stages, NULL, + TX_PARAM_NONE); + printf("transaction started\n"); + //Write + printf("Starting a write\n"); for (e = k->List; e != End; e = e->Next) { + //printf("adding %p to tx\n", e->Addr); + pmemobj_tx_add_range_direct(e->Addr, 1); *(e->Addr) = e->Valu; } + printf("Written to pmem\n"); + //Commit + pmemobj_tx_commit(); + printf("Commited\n"); + pmemobj_tx_end(); + printf("Ended\n"); + } void @@ -277,6 +306,7 @@ txReset (Thread* Self) __INLINE__ void txCommitReset (Thread* Self) { + printf("Attempt to reset\n"); txReset(Self); Self->Retries = 0; } @@ -325,7 +355,7 @@ backoff (Thread* Self, long attempt) __INLINE__ long -TryFastUpdate (Thread* Self) +TryFastUpdate (Thread* Self, PMEMobjpool *pop) { Log* const wr = &Self->wrSet; long ctr; @@ -339,7 +369,7 @@ TryFastUpdate (Thread* Self) } { - WriteBackForward(wr); /* write-back the deferred stores */ + WriteBackForward(wr, pop); /* write-back the deferred stores */ } MEMBARSTST(); /* Ensure the above stores are visible */ LOCK->value = Self->snapshot + 2; @@ -351,6 +381,7 @@ TryFastUpdate (Thread* Self) void TxAbort (Thread* Self) { + printf("TX aborted\n"); Self->Retries++; Self->Aborts++; @@ -445,7 +476,7 @@ TxStart (Thread* Self, sigjmp_buf* envPtr) } int -TxCommit (Thread* Self) +TxCommit (Thread* Self, PMEMobjpool *pop) { /* Fast-path: Optional optimization for pure-readers */ if (Self->wrSet.put == Self->wrSet.List) @@ -454,7 +485,8 @@ TxCommit (Thread* Self) return 1; } - if (TryFastUpdate(Self)) { + if (TryFastUpdate(Self, pop)) { + printf("Calling reset after tryFastUpdate\n"); txCommitReset(Self); return 1; } @@ -464,7 +496,7 @@ TxCommit (Thread* Self) } int -TxCommitSTM (Thread* Self) +TxCommitSTM (Thread* Self, PMEMobjpool *pop) { /* Fast-path: Optional optimization for pure-readers */ if (Self->wrSet.put == Self->wrSet.List) @@ -473,7 +505,7 @@ TxCommitSTM (Thread* Self) return 1; } - if (TryFastUpdate(Self)) { + if (TryFastUpdate(Self, pop)) { txCommitReset(Self); return 1; } @@ -510,8 +542,9 @@ long TxValidate (Thread* Self) { } -long TxFinalize (Thread* Self, long clock) { +long TxFinalize (Thread* Self, long clock, PMEMobjpool *pop) { if (Self->wrSet.put == Self->wrSet.List) { + printf("Calling commit reset in TXFinalize\n"); txCommitReset(Self); return 0; } @@ -521,12 +554,13 @@ long TxFinalize (Thread* Self, long clock) { } Log* const wr = &Self->wrSet; - WriteBackForward(wr); /* write-back the deferred stores */ + WriteBackForward(wr, pop); /* write-back the deferred stores */ LOCK->value += LOCK->value + 2; return 0; } void TxResetAfterFinalize (Thread* Self) { + printf("Calling commit reset after TXFinalize\n"); txCommitReset(Self); } diff --git a/norec/norec.h b/norec/norec.h index b85d7a7bd9a01ea44a35ee0027dade0b271a06d0..38c1820b67a4e9267f670de8aa146800a7b93b48 100644 --- a/norec/norec.h +++ b/norec/norec.h @@ -59,7 +59,7 @@ extern "C" { - +#include <libpmemobj/base.h> # include <setjmp.h> # define SIGSETJMP(env, savesigs) sigsetjmp(env, savesigs) # define SIGLONGJMP(env, val) siglongjmp(env, val); assert(0) @@ -83,8 +83,8 @@ Thread* TxNewThread (); void TxFreeThread (Thread*); void TxInitThread (Thread*, long id); -int TxCommit (Thread*); -int TxCommitSTM (Thread*); +int TxCommit (Thread*, PMEMobjpool *pop); +int TxCommitSTM (Thread*, PMEMobjpool *pop); void TxAbort (Thread*); intptr_t TxLoad (Thread*, volatile intptr_t*); void TxStore (Thread*, volatile intptr_t*, intptr_t); @@ -98,7 +98,7 @@ void TxFree (Thread*, void*); void TxIncClock (); long TxValidate (Thread*); -long TxFinalize (Thread*, long); +long TxFinalize (Thread*, long, PMEMobjpool *pop); void TxResetAfterFinalize (Thread*);