single socketpool version with spin locks
authoradash <adash>
Fri, 4 Apr 2008 18:20:49 +0000 (18:20 +0000)
committeradash <adash>
Fri, 4 Apr 2008 18:20:49 +0000 (18:20 +0000)
Robust/src/Runtime/DSTM/interface/sockpool.c [new file with mode: 0644]
Robust/src/Runtime/DSTM/interface/sockpool.h [new file with mode: 0644]

diff --git a/Robust/src/Runtime/DSTM/interface/sockpool.c b/Robust/src/Runtime/DSTM/interface/sockpool.c
new file mode 100644 (file)
index 0000000..80ea38c
--- /dev/null
@@ -0,0 +1,139 @@
+#include "sockpool.h"
+
+sockPoolHashTable_t sockhash;
+
+inline int CompareAndSwap(int *a, int oldval, int newval) {
+    int temp = *a;
+    if (temp == oldval) {
+        *a = newval;
+        return 1;
+    } else 
+        return 0;
+    return 1;
+}
+
+inline void InitLock(SpinLock *s) {
+    *s = 0;
+}
+
+inline void Lock(SpinLock *s) {
+    do {
+    } while(CompareAndSwap(s, 1, 1));
+}
+
+inline void UnLock(SpinLock *s) {
+    *s = 0;
+}
+
+int createSockPool(unsigned int size, float loadfactor) {
+    socknode_t **nodelist;
+    if ((nodelist = calloc(size, sizeof(socknode_t *))) < 0) {
+        printf("Calloc error at %s line %d\n", __FILE__, __LINE__);
+        return -1;
+    }
+    socknode_t **inuselist;
+    if ((inuselist = calloc(size, sizeof(socknode_t *))) < 0) {
+        printf("Calloc error at %s line %d\n", __FILE__, __LINE__);
+        free(nodelist);
+        return -1;
+    }
+    sockhash.table = nodelist;
+    sockhash.inuse = inuselist;
+    sockhash.size = size;
+    sockhash.numelements = 0;
+    sockhash.loadfactor = loadfactor;
+    InitLock(&sockhash.mylock);
+    return 0;
+}
+
+int createNewSocket(unsigned int mid) {
+    int sd;
+    if((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+        printf("%s() Error: In creating socket at %s, %d\n", __func__, __FILE__, __LINE__);
+        return -1;
+    }
+    struct sockaddr_in remoteAddr;
+    bzero(&remoteAddr, sizeof(remoteAddr));
+    remoteAddr.sin_family = AF_INET;
+    remoteAddr.sin_port = htons(LISTEN_PORT);
+    remoteAddr.sin_addr.s_addr = htonl(mid);
+    if(connect(sd, (struct sockaddr *)&remoteAddr, sizeof(remoteAddr)) < 0) {
+        printf("%s(): Error %d connecting to %s:%d\n", __func__, errno, inet_ntoa(remoteAddr.sin_addr), LISTEN_PORT);
+        close(sd);
+        return -1;
+    }
+    return sd;
+}
+
+int getSock(unsigned int mid) {
+    int key = mid%(sockhash.size);
+
+    Lock(&sockhash.mylock);
+    if (sockhash.table[key] == NULL) {
+        UnLock(&sockhash.mylock);
+        int sd;
+        if((sd = createNewSocket(mid)) != -1) {
+            socknode_t *inusenode = calloc(1, sizeof(socknode_t));
+            inusenode->mid = mid; 
+            inusenode->sd = sd; 
+            insToList(inusenode);
+            return sd;
+        } else {
+            return -1;
+        }
+    }
+    UnLock(&sockhash.mylock);
+    int midFound = 0;
+    Lock(&sockhash.mylock);
+    socknode_t *ptr = sockhash.table[key];
+    while (ptr != NULL) {
+        if (mid == ptr->mid) {
+            midFound = 1;
+            int sd = ptr->sd;
+            UnLock(&sockhash.mylock);
+            insToList(ptr);
+            return sd;
+        }
+        ptr = ptr->next;
+    }
+    UnLock(&sockhash.mylock);
+    if(midFound == 0) {
+        int sd;
+        if((sd = createNewSocket(mid)) != -1) {
+            socknode_t *inusenode = calloc(1, sizeof(socknode_t));
+            inusenode->mid = mid; 
+            inusenode->sd = sd; 
+            insToList(inusenode);
+            return sd;
+        } else {
+            return -1;
+        }
+    }
+    return -1;
+}
+
+int insToList(socknode_t *inusenode) {
+    int key = (inusenode->mid)%(sockhash.size);
+    Lock(&sockhash.mylock);
+    inusenode->next = sockhash.inuse[key];
+    sockhash.inuse[key] = inusenode;
+    UnLock(&sockhash.mylock);
+    return 0;
+} 
+
+int freeSock(unsigned int mid, int sd) {
+    int key = mid%(sockhash.size);
+
+    Lock(&sockhash.mylock);
+    socknode_t *ptr = sockhash.inuse[key]; 
+    ptr->mid = mid;
+    ptr->sd = sd;
+    sockhash.inuse[key] = ptr->next;
+    ptr->next = sockhash.table[key];
+    sockhash.table[key] = ptr;
+    UnLock(&sockhash.mylock);
+}
+
+int deleteSockpool(sockPoolHashTable_t *sockhash) {
+    free(sockhash->table);
+}
diff --git a/Robust/src/Runtime/DSTM/interface/sockpool.h b/Robust/src/Runtime/DSTM/interface/sockpool.h
new file mode 100644 (file)
index 0000000..185da85
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef _SOCKPOOL_H_
+#define _SOCKPOOL_H_
+
+#include "dstm.h"
+
+#define LOADFACTOR 0.5
+
+typedef int SpinLock;
+
+typedef struct socknode {
+    int sd;
+    unsigned int mid;
+    struct socknode *next;
+} socknode_t;
+
+typedef struct sockPoolHashTable {
+    socknode_t **table;
+    socknode_t **inuse;
+    unsigned int size;
+    unsigned int numelements;
+    float loadfactor;
+    SpinLock mylock;
+} sockPoolHashTable_t;
+
+int createSockPool(unsigned int, float);
+int getSock(unsigned int);
+int freeSock(unsigned int, int);
+int deleteSockpool(sockPoolHashTable_t *);
+int insToList(socknode_t *);
+int createNewSocket(unsigned int);
+int CompareAndSwap(int *, int, int);
+void InitLock(SpinLock *);
+void Lock (SpinLock *);
+void UnLock (SpinLock *);
+
+#endif