without signalHelper, HelperLock_, and any related thing to these

parent 8f151db5
......@@ -268,8 +268,8 @@ set (LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
# message ("Defaulting to build all tests")
# add_subdirectory (tests)
#else ()
# message ("Building only data structures")
# add_subdirectory (tests/data_structures)
message ("Building only data structures")
add_subdirectory (tests/data_structures)
#endif ()
add_subdirectory (src)
......
/home/vgogte/SFR/Atlas/runtime/scripts
\ No newline at end of file
......@@ -85,16 +85,16 @@ public:
// void setRegionId(region_id_t id) { RegionId_ = id; }
// region_id_t getRegionId() const { return RegionId_; }
void acquireLogReadyLock()
{ int status = pthread_mutex_lock(&HelperLock_); assert(!status); }
void releaseLogReadyLock()
{ int status = pthread_mutex_unlock(&HelperLock_); assert(!status); }
// void acquireLogReadyLock()
// { int status = pthread_mutex_lock(&HelperLock_); assert(!status); }
// void releaseLogReadyLock()
// { int status = pthread_mutex_unlock(&HelperLock_); assert(!status); }
// void waitLogReady() {
// int status = pthread_cond_wait(&HelperCondition_, &HelperLock_);
// assert(!status);
// }
void signalLogReady()
{ int status = pthread_cond_signal(&HelperCondition_); assert(!status); }
// void signalLogReady()
// { int status = pthread_cond_signal(&HelperCondition_); assert(!status); }
// bool cmpXchngWeakLogPointer(LogStructure *expected,
// LogStructure *desired,
......@@ -200,14 +200,14 @@ private:
// Same as above but during recovery
std::atomic<LogStructure*> RecoveryTimeLsp_;
//
// indicator whether the user threads are done
std::atomic<int> AllDone_;
// indicator whether the user threads are done
// std::atomic<int> AllDone_;
//
// Condition variable thru which user threads signal the helper thread
pthread_cond_t HelperCondition_;
// pthread_cond_t HelperCondition_;
// Mutex for the above condition variable
pthread_mutex_t HelperLock_;
// pthread_mutex_t HelperLock_;
//
// Used to map a lock address to a pointer to LastReleaseInfo, the
// structure used to maintain information about the last release
......@@ -298,7 +298,7 @@ private:
CbLogList_{nullptr},
LogStructureHeaderPtr_{nullptr},
RecoveryTimeLsp_{nullptr},
AllDone_{0},
// AllDone_{0},
// Stats_{nullptr},
IsInitialized_{false}
{
......
......@@ -115,10 +115,10 @@ void LogMgr::finalize()
#ifdef _FORCE_FAIL
fail_program();
#endif
acquireLogReadyLock();
AllDone_.store(1, std::memory_order_release);
releaseLogReadyLock();
signalLogReady();
// acquireLogReadyLock();
// AllDone_.store(1, std::memory_order_release);
// releaseLogReadyLock();
// signalLogReady();
// int status = pthread_join(HelperThread_, nullptr);
// assert(!status);
......@@ -147,11 +147,11 @@ void LogMgr::signalHelper()
fail_program();
#endif
++TL_LogCount_;
if (TL_LogCount_ == kWorkThreshold) {
int status = pthread_cond_signal(&HelperCondition_);
assert(!status);
TL_LogCount_ = 0;
}
// if (TL_LogCount_ == kWorkThreshold) {
// int status = pthread_cond_signal(&HelperCondition_);
// assert(!status);
// TL_LogCount_ = 0;
// }
}
/////
......
......@@ -14,15 +14,15 @@
#
# data_structures CMakeLists
add_subdirectory (TATP)
add_subdirectory (RB)
add_subdirectory (TPCC)
add_subdirectory (CQ)
#add_subdirectory (TATP)
#add_subdirectory (RB)
#add_subdirectory (TPCC)
#add_subdirectory (CQ)
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/tests/data_structures)
set (DS_ATLAS_TGTS alarm_clock_nvm stores_nvm cow_array_list_nvm sll_nvm sll_mt_ll sll_ll pc_nvm sps_nvm linked_list_nvm)
set (DS_NOATLAS_TGTS cow_array_list queue sll sll_mt stores alarm_clock)
set (DS_ATLAS_TGTS stores_nvm )
set (DS_NOATLAS_TGTS stores)
set (DS_ALL_TGTS ${DS_ATLAS_TGTS} ${DS_NOATLAS_TGTS})
foreach (t ${DS_ALL_TGTS})
......
/home/sara/SFR-newAuthorCode/Sara_coupled/sara_coupled/Atlas/runtime/tests/data_structures/CQ
\ No newline at end of file
#
# (c) Copyright 2016 Hewlett Packard Enterprise Development LP
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version. This program is
# distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details. You should have received a copy of the GNU Lesser
# General Public License along with this program. If not, see
# <http://www.gnu.org/licenses/>.
#
# data_structures CMakeLists
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/tests/data_structures)
set (DS_ATLAS_TOP cq_nvm)
set (DS_ATLAS_TGTS cq cq_nvm)
set (DS_ALL_TGTS ${DS_ATLAS_TGTS})
file(GLOB_RECURSE SRC_FILES ${CMAKE_CURRENT_LIST_DIR}/*.cc)
#foreach (t ${DS_ALL_TGTS})
# if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/${t}.c")
# add_executable (${DS_ATLAS_TOP} "${t}.c")
# elseif (EXISTS "${CMAKE_CURRENT_LIST_DIR}/${t}.cpp")
# add_executable (${DS_ATLAS_TOP} "${t}.cpp")
# else ()
# add_executable (${DS_ATLAS_TOP} "${t}.cc")
# endif ()
#endforeach()
add_executable (${DS_ATLAS_TOP} ${SRC_FILES})
foreach (t ${DS_ATLAS_TOP})
set_target_properties(${t} PROPERTIES COMPILE_FLAGS "${APP_FLAGS}")
target_link_libraries (${t} pthread rt)
endforeach ()
foreach (t ${DS_ATLAS_TOP})
get_target_property (TEMP_PROPERTY ${t} COMPILE_FLAGS)
set_target_properties (${t} PROPERTIES COMPILE_FLAGS "${NVM_INSTR_FLAGS} ${TEMP_PROPERTY}")
target_link_libraries (${t} atlas pthread rt)
endforeach ()
#include "cq.h"
#include <iostream>
/******************************************
* tail-> item2 <- item1 <- item0 <- head *
* next<-item *
* push > tail...head > pop *
******************************************/
void concurrent_queue::push(int val) {
item *new_item = (item*)nvm_alloc(sizeof(item), rgn_id);
// node->val = val;
pthread_mutex_lock(&enq_lock);
for (int i = 0; i < num_sub_items; i++) {
(new_item->si + i)->val = val;
}
new_item->next = NULL;
tail->next = new_item;
tail = new_item;
pthread_mutex_unlock(&enq_lock);
}
bool concurrent_queue::pop(int &out) {
pthread_mutex_lock(&deq_lock);
item *node = head;
item *new_head = node->next;
if (new_head == NULL) {
pthread_mutex_unlock(&deq_lock);
return false;
}
out = (new_head->si)->val;
head = new_head;
pthread_mutex_unlock(&deq_lock);
nvm_free(node);
return true;
}
void concurrent_queue::init(uint32_t r, int n) {
rgn_id = r;
num_sub_items = n;
item *new_item = (item *)nvm_alloc(sizeof(item), rgn_id);
for (int i = 0; i < num_sub_items; i++) {
(new_item->si + i)->val = -1;
}
new_item->next = NULL;
head = new_item;
tail = new_item;
}
concurrent_queue::concurrent_queue() {
//init 32MB mem
// tail = (item**)persistent_malloc(sizeof(item*));
// std::cout << tail << std::endl;
// std::cout << *tail << std::endl;
// *tail = (item*)persistent_malloc(sizeof(item)*1024);
// start = *tail;
// item* temp = (item*) start;
// for (int i=0; i<1024; i++) {
// temp->next = NULL;
// for (int i = 0; i < num_sub_items; i++) {
// (temp->si + i)->val = 0;
// }
// temp++;
// }
head = NULL;
tail = NULL;
q_size = 0;
//initialize mutex and cv
pthread_mutex_init(&enq_lock,NULL);
pthread_mutex_init(&deq_lock,NULL);
// enq_lock.initialize();
// deq_lock.initialize();
}
concurrent_queue::~concurrent_queue() {
//atomic_trace::persist_barrier(0 | RACE_BAR);
// free(start);
}
#include <vector>
#include <pthread.h>
#include <cstdlib>
#include <pthread.h>
#include <cstdint>
// Atlas includes
#include "atlas_alloc.h"
#include "atlas_api.h"
#define NUM_SUB_ITEMS 64
typedef struct item item;
struct sub_item {
int val;
sub_item& operator=(sub_item& other) {
val = other.val;
return *this;
}
};
struct item {
item* next;
sub_item si[NUM_SUB_ITEMS];
item() {
next = NULL;
};
item& operator=(item& other) {
for (int i= 0; i< NUM_SUB_ITEMS; i++) {
*(si + i) = *(other.si + i);
}
return *this;
}
};
class concurrent_queue {
pthread_mutex_t enq_lock;
pthread_mutex_t deq_lock;
//pthread_cond_t isEmpty_cv;
int q_size;
item *head;
item *tail;
int rgn_id;
int num_sub_items;
public:
concurrent_queue();
~concurrent_queue();
void push(int);
bool pop(int&);
void init(uint32_t r, int n);
};
#include "cq.h"
#include <iostream>
#include <cstdlib>
#include <sys/time.h>
#include <unistd.h>
// Atlas includes
#include "atlas_alloc.h"
#include "atlas_api.h"
#include "../cpu_util.h"
#include <string>
#include <fstream>
#define NUM_SUB_ITEMS 64
#define NUM_OPS 1000000
#define NUM_THREADS 12
uint32_t cq_rgn_id;
concurrent_queue* CQ;
void initialize() {
// void *rgn_root = NVM_GetRegionRoot(pc_rgn_id);
// if (rgn_root) {
// P = (PC *)rgn_root;
//
// D->lock_ = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
// pthread_mutex_init(D->lock_, NULL);
//
// std::cout << "Found queue at %p" << (void *)Q << std::endl;
// traverse();
// } else {
CQ = (concurrent_queue*)nvm_alloc(sizeof(concurrent_queue), cq_rgn_id);
CQ->init(cq_rgn_id, NUM_SUB_ITEMS);
fprintf(stderr, "Created cq at %p\n", (void *)CQ);
// Set the root of the Atlas persistent region
NVM_SetRegionRoot(cq_rgn_id, CQ);
// }
}
void* run_stub(void* ptr) {
for (int i = 0; i < NUM_OPS/NUM_THREADS; ++i) {
int coin = rand();
// if (coin % 2) {
CQ->push(i);
// }
// else {
// int val;
// CQ->pop(val);
// }
// if(i%1000000==0) std::cout << "Num ops: " << i << std::endl;
}
// std::cout << "User done\n";
NVM_UsrDone();
// std::cout << "Out of here\n";
return NULL;
}
int main(int argc, char** argv) {
//pthread_mutex_init(&output, NULL);
std::cout << "In main\n" << std::endl;
struct timeval tv_start;
struct timeval tv_end;
cpuUtil ut_start;
cpuUtil ut_end;
std::ofstream fexec;
std::ofstream futil;
fexec.open("exec.csv",std::ios_base::app);
futil.open("util.csv",std::ios_base::app);
// Initialize Atlas
NVM_Initialize();
// Create an Atlas persistent region
cq_rgn_id = NVM_FindOrCreateRegion("cq", O_RDWR, NULL);
// This contains the Atlas restart code to find any reusable data
initialize();
pthread_t threads[NUM_THREADS];
getUtil(ut_start);
gettimeofday(&tv_start, NULL);
for (int i = 0; i < NUM_THREADS; ++i) {
pthread_create(&threads[i], NULL, &run_stub, NULL);
}
// sleep(5);
NVM_UsrDone();
for (int i = 0; i < NUM_THREADS; ++i) {
pthread_join(threads[i], NULL);
}
gettimeofday(&tv_end, NULL);
getUtil(ut_end);
fprintf(stderr, "time elapsed %ld us\n",
tv_end.tv_usec - tv_start.tv_usec +
(tv_end.tv_sec - tv_start.tv_sec) * 1000000);
fprintf(stderr, "cpu util %f\n",getAvgUtil(ut_start,ut_end));
fexec << "CQ" << ", " << std::to_string((tv_end.tv_usec - tv_start.tv_usec) + (tv_end.tv_sec - tv_start.tv_sec) * 1000000) << std::endl;
futil << "CQ" << ", " << std::to_string(getAvgUtil(ut_start,ut_end)) << std::endl;
fexec.close();
futil.close();
// Close the Atlas persistent region
NVM_CloseRegion(cq_rgn_id);
// Optionally print Atlas stats
#ifdef NVM_STATS
NVM_PrintStats();
#endif
// printf("Finalizing NVM region\n");
// Atlas bookkeeping
NVM_Finalize();
return 0;
}
/home/sara/SFR-newAuthorCode/Sara_coupled/sara_coupled/Atlas/runtime/tests/data_structures/RB
\ No newline at end of file
#
# (c) Copyright 2016 Hewlett Packard Enterprise Development LP
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version. This program is
# distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details. You should have received a copy of the GNU Lesser
# General Public License along with this program. If not, see
# <http://www.gnu.org/licenses/>.
#
# data_structures CMakeLists
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/tests/data_structures)
set (DS_ATLAS_TOP rb_nvm)
set (DS_ATLAS_TGTS rb rb_nvm)
set (DS_ALL_TGTS ${DS_ATLAS_TGTS})
file(GLOB_RECURSE SRC_FILES ${CMAKE_CURRENT_LIST_DIR}/*.cc)
#foreach (t ${DS_ALL_TGTS})
# if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/${t}.c")
# add_executable (${DS_ATLAS_TOP} "${t}.c")
# elseif (EXISTS "${CMAKE_CURRENT_LIST_DIR}/${t}.cpp")
# add_executable (${DS_ATLAS_TOP} "${t}.cpp")
# else ()
# add_executable (${DS_ATLAS_TOP} "${t}.cc")
# endif ()
#endforeach()
add_executable (${DS_ATLAS_TOP} ${SRC_FILES})
foreach (t ${DS_ATLAS_TOP})
set_target_properties(${t} PROPERTIES COMPILE_FLAGS "${APP_FLAGS}")
target_link_libraries (${t} pthread rt)
endforeach ()
foreach (t ${DS_ATLAS_TOP})
get_target_property (TEMP_PROPERTY ${t} COMPILE_FLAGS)
set_target_properties (${t} PROPERTIES COMPILE_FLAGS "${NVM_INSTR_FLAGS} ${TEMP_PROPERTY}")
target_link_libraries (${t} atlas pthread rt)
endforeach ()
This diff is collapsed.
#include <vector>
#include <set>
#include <pthread.h>
#include <cstdlib>
#include <iostream>
#include <assert.h>
//#include "../atomic-memory-trace-master/src/annotation.h"
//
//#define BPFS_BAR atomic_trace::BPFS_BAR // BPFS barrier
//#define RACE_BAR atomic_trace::RACE_BAR // Epoch barrier
//#define IMMEDIATE_BAR atomic_trace::IMMEDIATE_BAR // Epoch barrier under strand
//#define INDEPENDENT_BAR atomic_trace::INDEPENDENT_BAR // Strand barrier
#define TREE_LENGTH 100
//#define MAX_LEN 4096 // Max total size = 512KB
#define MAX_LEN 16384 // Max total size = 512KB
typedef enum { RED, BLACK } Color;
struct Node {
int val;
Color color;
Node *left, *right, *parent;
char padding [64 - sizeof(int) - sizeof(Color) - 3 * sizeof(Node*)+64];
Node(int _val) {
val = _val;
left = NULL;
right = NULL;
parent = NULL;
color = BLACK;
}
};
// Red Black Tree algorithm from:
// http://www.cnblogs.com/skywang12345/p/3624291.html
// This blog uses the algorithm from "Introduction to Algorithms".
// Create two identical trees in the constructor.
// Modify one of them and record the nodes moved.
// Once done, change sel bit. Copy the modified nodes to the other tree.
// Backup tree will be used interchangeably.
// sel = 0: root_1 is valid.
// sel = 1: root_2 is valid.
// root_1 is stored in lower memory address
class Red_Black_Tree {
// roots of the two trees
Node* root_1;
Node* root_2;
// the current end ptrs of the two trees
Node* tree_1_end;
Node* tree_2_end;
// the original start ptrs given by driver function
// note: the root is not always the start ptr, since root may change
Node* start_1;
Node* start_2;
// sel tells which tree is the backup tree, stored in NVmem
// *sel = 0: root_1 is root
bool* sel;
// c++ 98 does not support unordered_set (O(1) insertion/deletion),
// so we use "std::vector". Although that may cause duplicated operations
// on the same node, the total complexity remains O(log(n)). However, using
// "std::set" will increase it to O((log(n))^2).
// FIXME: there might be redundant changes of node recorded.
std::vector<Node*> changed_nodes;
// mutex for the whole tree
// note: this program has NO parallelism. Using mutex only creates a
// thread-safe tree
pthread_mutex_t lock_1;
pthread_mutex_t lock_2;
int rgn_id;
// helper functions
void changeRoot(Node* x);
Node* getRoot();
void clearChange();
Node* createNode(int _val);
// Only record changes in the current tree
void recordChange(Node* node);
// Apply the changes in the current tree to the backup tree and change
// the sel bit
void copy_changes();
// Convert the current node address to its corresponding node in backup tree
Node* getBackupAddress(Node* node);
// lock the whole current tree
void lock();
// unlock the whole current tree
void unlock();
// tree operations
void left_rotation(Node* x);
void right_rotation(Node* x);
void insert_fix_up(Node* z);
void delete_fix_up(Node* x, Node* y);
Node* successor(Node* x);
// If val is in the tree, return the ptr to the node, otherwise return NULL
Node* rb_search(int val);
// Create a new node at the end_ptr and increment the end_ptr;
// note: insertion will not reuse the deleted memory.
void rb_insert(int val);
void rb_insert(Node* x);
// delete node z
// note: Deletion will not actually free the memory occupied by z
// It will only set all pointers in z to be NULL and set the value
// to be 0.
void rb_delete(Node* z);
public:
Red_Black_Tree();
Red_Black_Tree(Node* root);
Red_Black_Tree(Node* root, int* array, unsigned length, int rgn_id);
~Red_Black_Tree();
void initialize(Node* root, int* array, unsigned length, int r);
// return false if did an insertion
// return true if did a deletion
// note: only rb_delete_or_insert is persistent and thread-safe!
bool rb_delete_or_insert(int val);
};
#include "rb.h"
#include <vector>
#include <iostream>
#include <cstdint>
#include <assert.h>
#include <pthread.h>
//#include <stdio.h>
//#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#include <string>
#include <fstream>
// Atlas includes
#include "atlas_alloc.h"
#include "atlas_api.h"
#include "../cpu_util.h"
#define TREE_LENGTH 100
#define NUM_UPDATES_PER_CS 4
#define NUM_OPS 1000000
#define NUM_THREADS 12
int* array;
//Red_Black_Tree* rb;
uint32_t rb_rgn_id;
Red_Black_Tree* RB;
void initialize() {
// void *rgn_root = NVM_GetRegionRoot(rb_rgn_id);
// if (rgn_root) {
// P = (PC *)rgn_root;
//
// D->lock_ = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
// pthread_mutex_init(D->lock_, NULL);
//
// std::cout << "Found queue at %p" << (void *)Q << std::endl;
// traverse();
// } else {
RB = (Red_Black_Tree *)nvm_alloc(sizeof(Red_Black_Tree), rb_rgn_id);
fprintf(stderr, "Created hashmap at %p\n", (void *)RB);
// Set the root of the Atlas persistent region
NVM_SetRegionRoot(rb_rgn_id, RB);
// }
}
void* run_stub(void* ptr) {
for (int i = 0; i < NUM_OPS/NUM_THREADS; ++i) {
// int num = rand() % (2 * TREE_LENGTH);
RB->rb_delete_or_insert(NUM_UPDATES_PER_CS);
// if(i%10000 == 0) std::cout << "Added elems: " << i << std::endl;
// std::cout << "added number " << num << std::endl;
}
// std::cout << "User Done\n";
NVM_UsrDone();
// std::cout << "out of here\n";
return NULL;
}
// check if the two trees contain the same values
void verify(Node* root) {
unsigned count = 0;
Node* curr = root;
while (count < MAX_LEN) {
int val_1, val_2;
val_1 = curr->val;
val_2 = (curr + MAX_LEN)->val;
assert(val_2 == val_1 && "Two trees do not contain the same values");
curr++;
count++;
}
}
int main(int argc, char** argv) {
std::cout << "In main\n" << std::endl;
struct timeval tv_start;
struct timeval tv_end;
cpuUtil ut_start;
cpuUtil ut_end;
std::ofstream fexec;
std::ofstream futil;
fexec.open("exec.csv",std::ios_base::app);
futil.open("util.csv",std::ios_base::app);
// Initialize Atlas
NVM_Initialize();
// Create an Atlas persistent region
rb_rgn_id = NVM_FindOrCreateRegion("rb", O_RDWR, NULL);
// This contains the Atlas restart code to find any reusable data
initialize();