Segfault fix in prefetch queue + additional macros for debugging
[IRC.git] / Robust / src / Runtime / DSTM / interface / sockpool.c
1 #include "sockpool.h"
2 #include <netinet/tcp.h>
3
4 #if defined(__i386__)
5 inline int test_and_set(volatile unsigned int *addr) {
6     int oldval;
7     /* Note: the "xchg" instruction does not need a "lock" prefix */
8     __asm__ __volatile__("xchgl %0, %1"
9         : "=r"(oldval), "=m"(*(addr))
10         : "0"(1), "m"(*(addr)));
11     return oldval;
12 }
13 inline void UnLock(volatile unsigned int *addr) {
14     int oldval;
15     /* Note: the "xchg" instruction does not need a "lock" prefix */
16     __asm__ __volatile__("xchgl %0, %1"
17         : "=r"(oldval), "=m"(*(addr))
18         : "0"(0), "m"(*(addr)));
19 }
20 #elif
21 #   error need implementation of test_and_set
22 #endif
23
24 #define MAXSPINS 1000
25
26 inline void Lock(volatile unsigned int *s) {
27   while(test_and_set(s)) {
28     int i=0;
29     while(*s) {
30       if (i++>MAXSPINS) {
31         sched_yield();
32         i=0;
33       }
34     }
35   }
36 }
37
38 sockPoolHashTable_t *createSockPool(sockPoolHashTable_t * sockhash, unsigned int size) {
39   if((sockhash = calloc(1, sizeof(sockPoolHashTable_t))) == NULL) {
40     printf("Calloc error at %s line %d\n", __FILE__, __LINE__);
41     return NULL;
42   }
43   
44   socknode_t **nodelist;
45   if ((nodelist = calloc(size, sizeof(socknode_t *))) < 0) {
46     printf("Calloc error at %s line %d\n", __FILE__, __LINE__);
47     free(sockhash);
48     return NULL;
49   }
50   
51   sockhash->table = nodelist;
52   sockhash->inuse = NULL;
53   sockhash->size = size;
54   sockhash->mylock=0;
55   
56   return sockhash;
57 }
58
59 int createNewSocket(unsigned int mid) {
60   int sd;
61   int flag=1;
62   if((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
63     printf("%s() Error: In creating socket at %s, %d\n", __func__, __FILE__, __LINE__);
64     return -1;
65   }
66   setsockopt(sd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag));
67   struct sockaddr_in remoteAddr;
68   bzero(&remoteAddr, sizeof(remoteAddr));
69   remoteAddr.sin_family = AF_INET;
70   remoteAddr.sin_port = htons(LISTEN_PORT);
71   remoteAddr.sin_addr.s_addr = htonl(mid);
72   if(connect(sd, (struct sockaddr *)&remoteAddr, sizeof(remoteAddr)) < 0) {
73     perror("socket connect: ");
74     printf("%s(): Error %d connecting to %s:%d\n", __func__, errno, inet_ntoa(remoteAddr.sin_addr), LISTEN_PORT);
75     close(sd);
76     return -1;
77   }
78   return sd;
79 }
80
81 int getSockWithLock(sockPoolHashTable_t *sockhash, unsigned int mid) {
82   socknode_t **ptr;
83   int key = mid%(sockhash->size);
84   int sd;
85   
86   Lock(&sockhash->mylock);
87   ptr=&(sockhash->table[key]);
88   
89   while(*ptr!=NULL) {
90     if (mid == (*ptr)->mid) {
91       socknode_t *tmp=*ptr;
92       sd = tmp->sd;
93       *ptr=tmp->next;
94       tmp->next=sockhash->inuse;
95       sockhash->inuse=tmp;
96       UnLock(&sockhash->mylock);
97       return sd;
98     }
99     ptr=&((*ptr)->next);
100   }
101   UnLock(&sockhash->mylock);
102   if((sd = createNewSocket(mid)) != -1) {
103     socknode_t *inusenode = calloc(1, sizeof(socknode_t));
104     insToListWithLock(sockhash, inusenode);
105     return sd;
106   } else {
107     return -1;
108   }
109 }
110
111 int getSock(sockPoolHashTable_t *sockhash, unsigned int mid) {
112   socknode_t **ptr;
113   int key = mid%(sockhash->size);
114   int sd;
115   
116   ptr=&(sockhash->table[key]);
117   
118   while(*ptr!=NULL) {
119     if (mid == (*ptr)->mid) {
120       socknode_t *tmp=*ptr;
121       sd = tmp->sd;
122       *ptr=tmp->next;
123       tmp->next=sockhash->inuse;
124       sockhash->inuse=tmp;
125       return sd;
126     }
127     ptr=&((*ptr)->next);
128   }
129   if((sd = createNewSocket(mid)) != -1) {
130     socknode_t *inusenode = calloc(1, sizeof(socknode_t));
131     inusenode->next=sockhash->inuse;
132     sockhash->inuse=inusenode;
133     return sd;
134   } else {
135     return -1;
136   }
137 }
138
139 int getSock2(sockPoolHashTable_t *sockhash, unsigned int mid) {
140   socknode_t **ptr;
141   int key = mid%(sockhash->size);
142   int sd;
143   
144   ptr=&(sockhash->table[key]);
145   
146   while(*ptr!=NULL) {
147     if (mid == (*ptr)->mid) {
148       return (*ptr)->sd;
149     }
150     ptr=&((*ptr)->next);
151   }
152   if((sd = createNewSocket(mid)) != -1) {
153     *ptr=calloc(1, sizeof(socknode_t));
154     (*ptr)->mid=mid;
155     (*ptr)->sd=sd;
156     return sd;
157   } else {
158     return -1;
159   }
160 }
161
162 void insToListWithLock(sockPoolHashTable_t *sockhash, socknode_t *inusenode) {
163     Lock(&sockhash->mylock);
164     inusenode->next = sockhash->inuse;
165     sockhash->inuse = inusenode;
166     UnLock(&sockhash->mylock);
167
168
169 void freeSock(sockPoolHashTable_t *sockhash, unsigned int mid, int sd) {
170     int key = mid%(sockhash->size);
171     socknode_t *ptr = sockhash->inuse; 
172     sockhash->inuse = ptr->next;
173     ptr->mid = mid;
174     ptr->sd = sd;
175     ptr->next = sockhash->table[key];
176     sockhash->table[key] = ptr;
177 }
178
179 void freeSockWithLock(sockPoolHashTable_t *sockhash, unsigned int mid, int sd) {
180   int key = mid%(sockhash->size);
181   socknode_t *ptr;
182   Lock(&sockhash->mylock);
183   ptr = sockhash->inuse; 
184   sockhash->inuse = ptr->next;
185   ptr->mid = mid;
186   ptr->sd = sd;
187   ptr->next = sockhash->table[key];
188   sockhash->table[key] = ptr;
189   UnLock(&sockhash->mylock);
190 }
191
192 #if 0
193 / ***************************************/
194 * Array Implementation for socket resuse 
195 * ***************************************/
196
197 int num_machines;
198
199 sock_pool_t *initSockPool(unsigned int *mid, int machines) {
200     sock_pool_t *sockpool;
201     num_machines = machines;
202     if ((sockpool = calloc(num_machines, sizeof(sock_pool_t))) < 0) {
203         printf("%s(), Calloc error at %s, line %d\n", __func__, __FILE__, __LINE__);
204         return NULL;
205     }
206     int i;
207     for (i = 0; i < num_machines; i++) {
208         if ((sockpool[i].sd = calloc(MAX_CONN_PER_MACHINE, sizeof(int))) < 0) {
209             printf("%s(), Calloc error at %s, line %d\n", __func__, __FILE__, __LINE__);
210             return NULL;
211         }
212         if ((sockpool[i].inuse = calloc(MAX_CONN_PER_MACHINE, sizeof(char))) < 0) {
213             printf("%s(), Calloc error at %s, line %d\n", __func__, __FILE__, __LINE__);
214             return NULL;
215         }
216         sockpool[i].mid = mid[i];
217         int j;
218         for(j = 0; j < MAX_CONN_PER_MACHINE; j++) {
219             sockpool[i].sd[j] = -1;
220         }
221     }
222
223     return sockpool;
224 }
225
226 int getSock(sock_pool_t *sockpool, unsigned int mid) {
227     int i;
228     for (i = 0; i < num_machines; i++) {
229         if (sockpool[i].mid == mid) {
230             int j;
231             for (j = 0; j < MAX_CONN_PER_MACHINE; j++) {
232                 if (sockpool[i].sd[j] != -1 && (sockpool[i].inuse[j] == 0)) {
233                     sockpool[i].inuse[j] = 1;
234                     return sockpool[i].sd[j];
235                 }
236                 if (sockpool[i].sd[j] == -1) {
237                     //Open Connection
238                     int sd;
239                     if((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
240                         printf("%s() Error: In creating socket at %s, %d\n", __func__, __FILE__, __LINE__);
241                         return -1;
242                     }
243                     struct sockaddr_in remoteAddr;
244                     bzero(&remoteAddr, sizeof(remoteAddr));
245                     remoteAddr.sin_family = AF_INET;
246                     remoteAddr.sin_port = htons(LISTEN_PORT);
247                     remoteAddr.sin_addr.s_addr = htonl(mid);
248
249                     if(connect(sd, (struct sockaddr *)&remoteAddr, sizeof(remoteAddr)) < 0) {
250                         printf("%s(): Error %d connecting to %s:%d\n", __func__, errno, inet_ntoa(remoteAddr.sin_addr), LISTEN_PORT);
251                         close(sd);
252                         return -1;
253                     }
254                     sockpool[i].sd[j] = sd;
255                     sockpool[i].inuse[j] = 1;
256                     return sockpool[i].sd[j];
257                 }
258             }
259             printf("%s()->Error: Less number of MAX_CONN_PER_MACHINE\n", __func__);
260             return -1;
261         }
262     }
263     printf("%s()-> Error: Machine id not found\n", __func__);
264
265     return -1;
266 }
267
268 int freeSock(sock_pool_t *sockpool, int sd) {
269     int i;
270     for (i = 0; i < num_machines; i++) {
271         int j;
272         for (j = 0; j < MAX_CONN_PER_MACHINE; j++) {
273             if (sockpool[i].sd[j] == sd) {
274                 sockpool[i].inuse[j] = 0;
275                 return 0;
276             }
277         }
278     }
279     printf("%s() Error: Illegal socket descriptor %d\n", __func__, sd);
280
281     return -1;
282 }
283
284 #endif