Udp invalidation of objects
[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     printf("%s(): Error %d connecting to %s:%d\n", __func__, errno, inet_ntoa(remoteAddr.sin_addr), LISTEN_PORT);
74     close(sd);
75     return -1;
76   }
77   return sd;
78 }
79
80 int getSockWithLock(sockPoolHashTable_t *sockhash, unsigned int mid) {
81   socknode_t **ptr;
82   int key = mid%(sockhash->size);
83   int sd;
84   
85   Lock(&sockhash->mylock);
86   ptr=&(sockhash->table[key]);
87   
88   while(*ptr!=NULL) {
89     if (mid == (*ptr)->mid) {
90       socknode_t *tmp=*ptr;
91       sd = tmp->sd;
92       *ptr=tmp->next;
93       tmp->next=sockhash->inuse;
94       sockhash->inuse=tmp;
95       UnLock(&sockhash->mylock);
96       return sd;
97     }
98     ptr=&((*ptr)->next);
99   }
100   UnLock(&sockhash->mylock);
101   if((sd = createNewSocket(mid)) != -1) {
102     socknode_t *inusenode = calloc(1, sizeof(socknode_t));
103     insToListWithLock(sockhash, inusenode);
104     return sd;
105   } else {
106     return -1;
107   }
108 }
109
110 int getSock(sockPoolHashTable_t *sockhash, unsigned int mid) {
111   socknode_t **ptr;
112   int key = mid%(sockhash->size);
113   int sd;
114   
115   ptr=&(sockhash->table[key]);
116   
117   while(*ptr!=NULL) {
118     if (mid == (*ptr)->mid) {
119       socknode_t *tmp=*ptr;
120       sd = tmp->sd;
121       *ptr=tmp->next;
122       tmp->next=sockhash->inuse;
123       sockhash->inuse=tmp;
124       return sd;
125     }
126     ptr=&((*ptr)->next);
127   }
128   if((sd = createNewSocket(mid)) != -1) {
129     socknode_t *inusenode = calloc(1, sizeof(socknode_t));
130     inusenode->next=sockhash->inuse;
131     sockhash->inuse=inusenode;
132     return sd;
133   } else {
134     return -1;
135   }
136 }
137
138 int getSock2(sockPoolHashTable_t *sockhash, unsigned int mid) {
139   socknode_t **ptr;
140   int key = mid%(sockhash->size);
141   int sd;
142   
143   ptr=&(sockhash->table[key]);
144   
145   while(*ptr!=NULL) {
146     if (mid == (*ptr)->mid) {
147       return (*ptr)->sd;
148     }
149     ptr=&((*ptr)->next);
150   }
151   if((sd = createNewSocket(mid)) != -1) {
152     *ptr=calloc(1, sizeof(socknode_t));
153     (*ptr)->mid=mid;
154     (*ptr)->sd=sd;
155     return sd;
156   } else {
157     return -1;
158   }
159 }
160
161 void insToListWithLock(sockPoolHashTable_t *sockhash, socknode_t *inusenode) {
162     Lock(&sockhash->mylock);
163     inusenode->next = sockhash->inuse;
164     sockhash->inuse = inusenode;
165     UnLock(&sockhash->mylock);
166
167
168 void freeSock(sockPoolHashTable_t *sockhash, unsigned int mid, int sd) {
169     int key = mid%(sockhash->size);
170     socknode_t *ptr = sockhash->inuse; 
171     sockhash->inuse = ptr->next;
172     ptr->mid = mid;
173     ptr->sd = sd;
174     ptr->next = sockhash->table[key];
175     sockhash->table[key] = ptr;
176 }
177
178 void freeSockWithLock(sockPoolHashTable_t *sockhash, unsigned int mid, int sd) {
179   int key = mid%(sockhash->size);
180   socknode_t *ptr;
181   Lock(&sockhash->mylock);
182   ptr = sockhash->inuse; 
183   sockhash->inuse = ptr->next;
184   ptr->mid = mid;
185   ptr->sd = sd;
186   ptr->next = sockhash->table[key];
187   sockhash->table[key] = ptr;
188   UnLock(&sockhash->mylock);
189 }
190
191 #if 0
192 / ***************************************/
193 * Array Implementation for socket resuse 
194 * ***************************************/
195
196 int num_machines;
197
198 sock_pool_t *initSockPool(unsigned int *mid, int machines) {
199     sock_pool_t *sockpool;
200     num_machines = machines;
201     if ((sockpool = calloc(num_machines, sizeof(sock_pool_t))) < 0) {
202         printf("%s(), Calloc error at %s, line %d\n", __func__, __FILE__, __LINE__);
203         return NULL;
204     }
205     int i;
206     for (i = 0; i < num_machines; i++) {
207         if ((sockpool[i].sd = calloc(MAX_CONN_PER_MACHINE, sizeof(int))) < 0) {
208             printf("%s(), Calloc error at %s, line %d\n", __func__, __FILE__, __LINE__);
209             return NULL;
210         }
211         if ((sockpool[i].inuse = calloc(MAX_CONN_PER_MACHINE, sizeof(char))) < 0) {
212             printf("%s(), Calloc error at %s, line %d\n", __func__, __FILE__, __LINE__);
213             return NULL;
214         }
215         sockpool[i].mid = mid[i];
216         int j;
217         for(j = 0; j < MAX_CONN_PER_MACHINE; j++) {
218             sockpool[i].sd[j] = -1;
219         }
220     }
221
222     return sockpool;
223 }
224
225 int getSock(sock_pool_t *sockpool, unsigned int mid) {
226     int i;
227     for (i = 0; i < num_machines; i++) {
228         if (sockpool[i].mid == mid) {
229             int j;
230             for (j = 0; j < MAX_CONN_PER_MACHINE; j++) {
231                 if (sockpool[i].sd[j] != -1 && (sockpool[i].inuse[j] == 0)) {
232                     sockpool[i].inuse[j] = 1;
233                     return sockpool[i].sd[j];
234                 }
235                 if (sockpool[i].sd[j] == -1) {
236                     //Open Connection
237                     int sd;
238                     if((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
239                         printf("%s() Error: In creating socket at %s, %d\n", __func__, __FILE__, __LINE__);
240                         return -1;
241                     }
242                     struct sockaddr_in remoteAddr;
243                     bzero(&remoteAddr, sizeof(remoteAddr));
244                     remoteAddr.sin_family = AF_INET;
245                     remoteAddr.sin_port = htons(LISTEN_PORT);
246                     remoteAddr.sin_addr.s_addr = htonl(mid);
247
248                     if(connect(sd, (struct sockaddr *)&remoteAddr, sizeof(remoteAddr)) < 0) {
249                         printf("%s(): Error %d connecting to %s:%d\n", __func__, errno, inet_ntoa(remoteAddr.sin_addr), LISTEN_PORT);
250                         close(sd);
251                         return -1;
252                     }
253                     sockpool[i].sd[j] = sd;
254                     sockpool[i].inuse[j] = 1;
255                     return sockpool[i].sd[j];
256                 }
257             }
258             printf("%s()->Error: Less number of MAX_CONN_PER_MACHINE\n", __func__);
259             return -1;
260         }
261     }
262     printf("%s()-> Error: Machine id not found\n", __func__);
263
264     return -1;
265 }
266
267 int freeSock(sock_pool_t *sockpool, int sd) {
268     int i;
269     for (i = 0; i < num_machines; i++) {
270         int j;
271         for (j = 0; j < MAX_CONN_PER_MACHINE; j++) {
272             if (sockpool[i].sd[j] == sd) {
273                 sockpool[i].inuse[j] = 0;
274                 return 0;
275             }
276         }
277     }
278     printf("%s() Error: Illegal socket descriptor %d\n", __func__, sd);
279
280     return -1;
281 }
282
283 #endif