From c7755cc2345bbef2ac2173154c68616c1351dc1a Mon Sep 17 00:00:00 2001 From: adash Date: Fri, 5 Feb 2010 02:50:47 +0000 Subject: [PATCH] complete sandbox implementation --- Robust/src/Runtime/DSTM/interface/dsmlock.c | 8 + Robust/src/Runtime/DSTM/interface/dsmlock.h | 3 + Robust/src/Runtime/DSTM/interface/dstm.h | 1 + .../src/Runtime/DSTM/interface/dstmserver.c | 22 +- Robust/src/Runtime/DSTM/interface/sandbox.c | 298 ++++++++++++++++-- Robust/src/Runtime/DSTM/interface/sandbox.h | 41 ++- Robust/src/Runtime/DSTM/interface/trans.c | 6 + 7 files changed, 337 insertions(+), 42 deletions(-) diff --git a/Robust/src/Runtime/DSTM/interface/dsmlock.c b/Robust/src/Runtime/DSTM/interface/dsmlock.c index e9839362..69cb4d67 100644 --- a/Robust/src/Runtime/DSTM/interface/dsmlock.c +++ b/Robust/src/Runtime/DSTM/interface/dsmlock.c @@ -61,3 +61,11 @@ inline void write_unlock(volatile int *rw) { __asm__ __volatile__ (LOCK_PREFIX "addl %1, %0" : "+m" (*rw) : "i" (RW_LOCK_BIAS) : "memory"); } + +inline int is_write_locked(volatile int *lock) { + return lock < 0; +} + +inline int is_read_locked(volatile int *lock) { + return lock > 0; +} diff --git a/Robust/src/Runtime/DSTM/interface/dsmlock.h b/Robust/src/Runtime/DSTM/interface/dsmlock.h index f95edf67..d0a5df84 100644 --- a/Robust/src/Runtime/DSTM/interface/dsmlock.h +++ b/Robust/src/Runtime/DSTM/interface/dsmlock.h @@ -1,6 +1,7 @@ #ifndef _DSMLOCK_H_ #define _DSMLOCK_H_ +#define CFENCE asm volatile("":::"memory"); #define RW_LOCK_BIAS 0x01000000 #define atomic_read(v) (*v) #define RW_LOCK_UNLOCKED { RW_LOCK_BIAS } @@ -22,4 +23,6 @@ static void atomic_add(int i, volatile int *v); static int atomic_sub_and_test(int i, volatile int *v); void read_unlock(volatile int *rw); void write_unlock(volatile int *rw); +int is_write_locked(volatile int *lock); +int is_read_locked(volatile int *lock); #endif diff --git a/Robust/src/Runtime/DSTM/interface/dstm.h b/Robust/src/Runtime/DSTM/interface/dstm.h index 5220a82d..b9791968 100644 --- a/Robust/src/Runtime/DSTM/interface/dstm.h +++ b/Robust/src/Runtime/DSTM/interface/dstm.h @@ -220,6 +220,7 @@ int dstmInit(void); void send_data(int fd, void *buf, int buflen); void recv_data(int fd, void *buf, int buflen); int recv_data_errorcode(int fd, void *buf, int buflen); +void recv_data_buf(int fd, struct readstruct *, void *, int); /* Prototypes for object header */ unsigned int getNewOID(void); diff --git a/Robust/src/Runtime/DSTM/interface/dstmserver.c b/Robust/src/Runtime/DSTM/interface/dstmserver.c index 64a7eb95..40554000 100644 --- a/Robust/src/Runtime/DSTM/interface/dstmserver.c +++ b/Robust/src/Runtime/DSTM/interface/dstmserver.c @@ -14,6 +14,9 @@ #include "gCollect.h" #include "readstruct.h" #include "debugmacro.h" +#ifdef SANDBOX +#include "sandbox.h" +#endif #define BACKLOG 10 //max pending connections #define RECEIVE_BUFFER_SIZE 2048 @@ -157,7 +160,6 @@ void *dstmAccept(void *acceptfd) { unsigned int oid; char *buffer; char control,ctrl; - char *ptr; void *srcObj; objheader_t *h; trans_commit_data_t transinfo; @@ -166,6 +168,11 @@ void *dstmAccept(void *acceptfd) { struct readstruct readbuffer; readbuffer.head=0; readbuffer.tail=0; + unsigned int numread=0, nummod=0; +#ifdef SANDBOX + objData_t odata; + char *ptr; +#endif /* Receive control messages from other machines */ while(1) { @@ -300,6 +307,17 @@ void *dstmAccept(void *acceptfd) { free(buffer); break; +#ifdef SANDBOX + case CHECK_OBJECTS: // check if versions of objects match + size = sizeof(odata) - 1; + ptr = (char*)&odata; + recv_data_buf((int)acceptfd, &readbuffer, ptr+1, size); + numread = odata.numread; + nummod = odata.nummod; + checkObjVersion(&readbuffer, (int) acceptfd, numread, nummod); + break; +#endif + case CLOSE_CONNECTION: goto closeconnection; @@ -329,7 +347,7 @@ int readClientReq(trans_commit_data_t *transinfo, int acceptfd, struct readstruc /* Read fixed_data_t data structure */ size = sizeof(fixed) - 1; - ptr = (char *)&fixed;; + ptr = (char *)&fixed; fixed.control = TRANS_REQUEST; recv_data_buf((int)acceptfd, readbuffer, ptr+1, size); diff --git a/Robust/src/Runtime/DSTM/interface/sandbox.c b/Robust/src/Runtime/DSTM/interface/sandbox.c index e4eea7a1..f1c0c7d7 100644 --- a/Robust/src/Runtime/DSTM/interface/sandbox.c +++ b/Robust/src/Runtime/DSTM/interface/sandbox.c @@ -1,26 +1,38 @@ -#include "sanbox.h" -#include "dstm.h" +#include "sandbox.h" #include "runtime.h" +#include "methodheaders.h" +__thread int transaction_check_counter; +__thread jmp_buf aborttrans; +__thread int abortenabled; +__thread int * counter_reset_pointer; +extern unsigned int myIpAddr; +extern sockPoolHashTable_t *transRequestSockPool; /* Do sandboxing */ void errorhandler(int sig, struct sigcontext ctx) { - //TODO modify this - if (sig == SIGSEGV) //Invalid memory segment access - printf("Got signal %d, faulty address is %p, " - "from %p\n", sig, ctx.cr2, ctx.eip); - else - printf("Got signal %d\n", sig); - + if (abortenabled&&checktrans()) { + sigset_t toclear; + sigemptyset(&toclear); + sigaddset(&toclear, sig); + sigprocmask(SIG_UNBLOCK, &toclear,NULL); +#ifdef TRANSSTATS + numTransAbort++; +#endif + objstrDelete(t_cache); + t_chashDelete(); + _longjmp(aborttrans, 1); + } threadhandler(sig, ctx); } int checktrans() { /* Create info to keep track of numelements */ unsigned int size = c_size; - chashlistnode_t *curr = c_table; + chashlistnode_t *ptr = c_table; int i; nodeElem_t *head=NULL; + numNode = 0; for(i = 0; i< size; i++) { chashlistnode_t *curr = &ptr[i]; /* Inner loop to traverse the linked list of the cache lookupTable */ @@ -32,19 +44,35 @@ int checktrans() { if (STATUS(headeraddr) & NEW || (mhashSearch(curr->key) != NULL)) { machinenum = myIpAddr; } else if ((machinenum = lhashSearch(curr->key)) == 0) { - printf("Error: No such machine %s, %d\n", __FILE__, __LINE__); + printf("Error: No such machine %s, %d\n", __func__, __LINE__); return 0; } - head = createList(head, headeraddr, machinenum, c_numelements); + if(machinenum != myIpAddr) + head = createList(head, headeraddr, machinenum, c_numelements); curr = curr->next; } } /* Send oid and versions for checking */ - verify(); + int retval=-1; + if(head != NULL) { + retval = verify(head); + } + + if(retval == 1) { + printf("Error in System at %s, %s(), %d\n", __FILE__, __func__, __LINE__); + print_trace(); + /* free head */ + deletehead(head); + exit(-1); + } + + if(retval == 0) { + /* free head */ + deletehead(head); + return 1; + } - //free head - deletehead(head); - return 0; + return 0; // return when objects inconsistent } nodeElem_t * createList(nodeElem_t *head, objheader_t *headeraddr, unsigned int mid, @@ -57,12 +85,16 @@ nodeElem_t * createList(nodeElem_t *head, objheader_t *headeraddr, unsigned int while(tmp != NULL) { if(tmp->mid == mid) { if (STATUS(headeraddr) & DIRTY) { - tmp->oidmod[tmp->nummod]->oid = OID(headeraddr); - tmp->oidmod[tmp->nummod]->version = headeraddr->version; + offset = (sizeof(unsigned int) + sizeof(short)) * tmp->nummod; + *((unsigned int *)(((char *)tmp->objmod) + offset))=OID(headeraddr); + offset += sizeof(unsigned int); + *((unsigned short *)(((char *)tmp->objmod) + offset)) = headeraddr->version; tmp->nummod++; } else { - tmp->oidread[tmp->numread]->oid = OID(headeraddr); - tmp->oidread[tmp->numread]->version = headeraddr->version; + offset = (sizeof(unsigned int) + sizeof(short)) * tmp->numread; + *((unsigned int *)(((char *)tmp->objread) + offset))=OID(headeraddr); + offset += sizeof(unsigned int); + *((unsigned short *)(((char *)tmp->objread) + offset)) = headeraddr->version; tmp->numread++; } found = 1; @@ -72,18 +104,24 @@ nodeElem_t * createList(nodeElem_t *head, objheader_t *headeraddr, unsigned int } //Add oid for any new machine if (!found) { + numNode++; ptr = makehead(c_numelements); if((ptr = makehead(c_numelements)) == NULL) { + printf("Error in Allocating memory %s, %d\n", __func__, __LINE__); return NULL; } ptr->mid = mid; if (STATUS(headeraddr) & DIRTY) { - ptr->oidmod[tmp->nummod]->oid = OID(headeraddr); - ptr->oidmod[tmp->nummod]->version = headeraddr->version; + offset = (sizeof(unsigned int) + sizeof(short)) * ptr->nummod; + *((unsigned int *)(((char *)ptr->objmod) + offset))=OID(headeraddr); + offset += sizeof(unsigned int); + *((unsigned short *)(((char *)ptr->objmod) + offset)) = headeraddr->version; ptr->nummod++; } else { - ptr->oidread[tmp->numread]->oid = OID(headeraddr); - ptr->oidread[tmp->numread]->version = headeraddr->version; + offset = (sizeof(unsigned int) + sizeof(short)) * ptr->numread; + *((unsigned int *)(((char *)ptr->objread) + offset))=OID(headeraddr); + offset += sizeof(unsigned int); + *((unsigned short *)(((char *)ptr->objread) + offset)) = headeraddr->version; ptr->numread++; } ptr->next = head; @@ -96,20 +134,23 @@ nodeElem_t * makehead(unsigned int numelements) { nodeElem_t *head; //Create the first element if((head = calloc(1, sizeof(nodeElem_t))) == NULL) { - printf("Calloc error %s %d\n", __FILE__, __LINE__); + printf("Calloc error %s %d\n", __func__, __LINE__); return NULL; } - if ((head->oidmod = calloc(numelements, sizeof(elem_t))) == NULL) { - printf("Calloc error %s %d\n", __FILE__, __LINE__); + + if ((head->objmod = calloc(numelements,sizeof(unsigned int) + sizeof(unsigned short))) == NULL) { + printf("Calloc error %s %d\n", __func__, __LINE__); free(head); return NULL; } - if ((head->oidread = calloc(numelements, sizeof(elem_t))) == NULL) { - printf("Calloc error %s %d\n", __FILE__, __LINE__); + + if ((head->objread = calloc(numelements,sizeof(unsigned int) + sizeof(unsigned short))) == NULL) { + printf("Calloc error %s %d\n", __func__, __LINE__); free(head); - free(head->oidmod); + free(head->objmod); return NULL; } + head->mid = 0; head->nummod = head->numread = 0; head->next = NULL; @@ -117,18 +158,207 @@ nodeElem_t * makehead(unsigned int numelements) { } //Delete the entire list -void pDelete(nodeElem_t *head) { +void deletehead(nodeElem_t *head) { nodeElem_t *next, *tmp; tmp = head; while(tmp != NULL) { next = tmp->next; - free(tmp->oidmod); - free(tmp->oidread); + free(tmp->objmod); + free(tmp->objread); free(tmp); tmp = next; } return; } -void verify() { +/* Process the linked list of objects */ +int verify(nodeElem_t *pile) { + /* create and initialize an array of sockets and reply receiving buffer */ + int sock[numNode]; + char getReplyCtrl[numNode]; + int i; + for(i=0; inumread; + tosend[pilecount].nummod = pile->nummod; + int sd = 0; + if((sd = getSock2WithLock(transRequestSockPool, pile->mid)) < 0) { + printf("Error: Getting a socket descriptor at %s(), %s(), %d\n", __FILE__, __func__, __LINE__); + exit(-1); + } + sock[pilecount] = sd; + + /* Send starting information of data */ + send_data(sd, &(tosend[pilecount]), sizeof(objData_t)); + + int size; + /* Send objetcs that are read */ + { + size=(sizeof(unsigned int)+sizeof(unsigned short)) * pile->numread; + send_data(sd, (char *)pile->objread, size); + } + + /* Send objects that are modified */ + { + size=(sizeof(unsigned int)+sizeof(unsigned short)) * pile->nummod; + send_data(sd, (char *)pile->objmod, size); + } + pilecount++; + pile = pile->next; + }// end of pile processing + + int checkObj = 0; + int countConsistent = 0; + + /* Recv replies from remote machines */ + for(i = 0; i Abort Transaction\n"); + return 0; + } + + if(countConsistent == numNode) { + return 1; + } + + return -1; +} + +void checkObjects() { + if (abortenabled&&checktrans()) { + printf("Loop Abort\n"); + transaction_check_counter=(*counter_reset_pointer=HIGH_CHECK_FREQUENCY); +#ifdef TRANSSTATS + numTransAbort++; +#endif + objstrDelete(t_cache); + t_chashDelete(); + _longjmp(aborttrans, 1); + } + transaction_check_counter=*counter_reset_pointer; +} + +/* Obtain a backtrace and print it to stdout */ +void print_trace() { + void *array[100]; + size_t size; + char ** strings; + size_t i; + + size = backtrace(array, 100); + strings = backtrace_symbols(array, size); + + printf ("Obtained %zd stack frames.\n", size); + for (i = 0; i < size; i++) + printf ("%s\n", strings[i]); + free (strings); +} + +void checkObjVersion(struct readstruct * readbuffer, int sd, unsigned int numread, unsigned int nummod) { + + int v_match=0; + + /* Recv objects read with versions */ + int size=(sizeof(unsigned int)+sizeof(unsigned short)) * numread; + char objread[size]; + if(numread != 0) { + recv_data_buf(sd, readbuffer, objread, size); + } + + /* Recv objects modified with versions */ + size=(sizeof(unsigned int)+sizeof(unsigned short)) * nummod; + char objmod[size]; + if(nummod != 0) { + recv_data_buf(sd, readbuffer, objmod, size); + } + + int i; + char control; + for(i=0; iversion) + v_match++; + else { + control = OBJ_INCONSISTENT; + send_data(sd, &control, sizeof(char)); + return; + } + } + } // end of objects read + + for(i=0; iversion) + v_match++; + else { + control = OBJ_INCONSISTENT; + send_data(sd, &control, sizeof(char)); + return; + } + } + } // end of objects modified + + if(v_match = (numread + nummod)) { + control = OBJ_CONSISTENT; + send_data(sd, &control, sizeof(char)); + } + return; } diff --git a/Robust/src/Runtime/DSTM/interface/sandbox.h b/Robust/src/Runtime/DSTM/interface/sandbox.h index b9844dff..d2f5fd6b 100644 --- a/Robust/src/Runtime/DSTM/interface/sandbox.h +++ b/Robust/src/Runtime/DSTM/interface/sandbox.h @@ -1,10 +1,30 @@ #ifndef SANDBOX_H #define SANDBOX_H +#include #include +#include "dstm.h" +#include "altmlookup.h" +#include +#include "readstruct.h" +#include "dsmlock.h" + extern __thread chashlistnode_t *c_table; extern __thread unsigned int c_size; extern __thread unsigned int c_numelements; +extern __thread jmp_buf aborttrans; +extern __thread int abortenabled; +extern __thread int* counter_reset_pointer; +extern __thread int transaction_check_counter; + + +/* Global Variables */ +#define CHECK_OBJECTS 51 +#define OBJ_INCONSISTENT 52 +#define OBJ_CONSISTENT 53 +#define LOW_CHECK_FREQUENCY 1000000 +#define HIGH_CHECK_FREQUENCY 100000 +int numNode; //variable to keep track of the length of the linked list of objects typedef struct elem { unsigned int oid; @@ -12,19 +32,28 @@ typedef struct elem { } elem_t; typedef struct nodeElem { - unsigned int mid; - unsigned int numread; - unsigned int nummod; - elem_t *oidread; - elem_t *oidmod; - struct nodeElem *next; + unsigned int mid; + unsigned int numread; + unsigned int nummod; + elem_t *objread; + elem_t *objmod; + struct nodeElem *next; } nodeElem_t; +typedef struct objData { + char control; + unsigned int numread; + unsigned int nummod; +} objData_t; + int checktrans(); void errorhandler(int sig, struct sigcontext ctx); nodeElem_t * makehead(unsigned int numelements); void deletehead(nodeElem_t *head); nodeElem_t * createList(nodeElem_t *, objheader_t *, unsigned int, unsigned int); +int verify(nodeElem_t *pile); +void print_trace(); +void checkObjVersion(struct readstruct*, int, unsigned int, unsigned int); #endif diff --git a/Robust/src/Runtime/DSTM/interface/trans.c b/Robust/src/Runtime/DSTM/interface/trans.c index 564100b7..d233b2df 100644 --- a/Robust/src/Runtime/DSTM/interface/trans.c +++ b/Robust/src/Runtime/DSTM/interface/trans.c @@ -914,6 +914,9 @@ int transCommit() { int firsttime=1; trans_commit_data_t transinfo; /* keeps track of objs locked during transaction */ char finalResponse; +#ifdef SANDBOX + abortenabled=0; +#endif #ifdef LOGEVENTS int iii; @@ -1172,6 +1175,9 @@ int transCommit() { /* Free Resources */ objstrDelete(t_cache); t_chashDelete(); +#ifdef SANDBOX + abortenabled=1; +#endif return TRANS_ABORT; } else if(finalResponse == TRANS_COMMIT) { #ifdef TRANSSTATS -- 2.34.1