8ae23aa9fb6d4eb20771536a1986fc2ff70abd1e
[vlp.git] / src / int / procaddr.c
1 #include        "depend.h"
2 #include        "genint.h"
3 #include        "int.h"
4 #include        "process.h"
5 #include        "intproto.h"
6
7 #include        <assert.h>
8
9 #define ldnode(addr)            ((word) (addr & 0xFF))
10 #define ldpix(addr)             ((word) ((addr >> 8) & 0xFF))
11 #define staddr(node, pix)       ((word) ((pix << 8) | node))
12
13
14 /*
15         These are converters from global to process pointers in memory
16         to global process pointers in message.
17         M denotes memory in which pair (pointer,object) exists or has to exist.
18         We want to create object denoting remote process instead of
19         dummy pointer without object.
20         The object will be like an arrayof integer of size 2.
21         arr[1..3] : arr[1]=node, arr[2]=pix.
22 */
23
24 void obj2mess(word *M, virtaddr *obj, procaddr *mess)
25 {
26 #ifdef OBJECTADDR
27         word am;
28         if(obj->mark != M[obj->addr + 1]){
29                 mess->node=-1;
30                 mess->pix =-1;
31                 mess->mark=-1;
32         } else {
33                 am=M[obj->addr];
34                 mess->node=M[am + 2];
35                 mess->pix =M[am + 3];
36                 mess->mark=M[am + 4];
37         }
38 #else
39         mess->node=ldnode(obj->addr);
40         mess->pix =ldpix (obj->addr);
41         mess->mark=obj->mark;
42 #endif
43 }
44
45 void mess2obj(procdescr *p, procaddr *mess, virtaddr *obj)
46 {
47 #ifdef OBJECTADDR
48         word am;
49         word *currM = M;
50         word currpix = thispix;
51
52         extern int compactify_allowed;
53         compactify_allowed = 0;
54         transfer(p - process);
55         hash_find(mess, obj);
56 /*
57         newarry(1, 4, APROCESS, obj, &am);
58         M[am + 2]=mess->node;
59         M[am + 3]=mess->pix;
60         M[am + 4]=mess->mark;
61 */
62         transfer(currpix);
63         M = currM;
64
65         compactify_allowed = 1;
66
67 #else
68         obj->addr=staddr(mess->node, mess->pix);
69         obj->mark=mess->mark;
70 #endif
71 }
72
73
74
75 bool isprocess(virtaddr *v) {
76 #ifdef OBJECTADDR
77         word am = M[v->addr];
78
79         /*assert(v->mark<=M[v->addr+1]);*/
80         if(v->mark != M[v->addr + 1] ) {
81                 return 0;
82         } else {
83                 return (M[am + 1] == APROCESS);
84         }
85 #else
86         return (v->mark < 0);
87 #endif
88 }
89
90
91
92 #ifdef OBJECTADDR
93
94 /* hash entry is a word pointing to dictionary or 0 if empty */
95
96 #ifndef NO_PROTOTYPES
97 static int hash_check_item(word, procaddr *);
98 static void hash_new_item(virtaddr *, procaddr *);
99 static int hash_mess(procaddr *);
100 static int hash_2(int);
101 #else
102 static int hash_check_item();
103 static void hash_new_item();
104 #endif
105
106 void hash_create(procdescr *p, int size) {
107         /* create hash table for p process */
108         int i;
109         if (p->hash != NULL)
110                 free(p->hash);
111         p->hash_size = size;
112         p->hash = mallocate(size);
113         if(p->hash == NULL)
114                 errsignal(RTEMEMOV);
115
116         for (i = 0; i < p->hash_size; i++)
117                 p->hash[i] = 0;
118 }
119
120
121 /**
122  * find pointer in hash table, add if not exists
123  */
124 void hash_find(procaddr *mess, virtaddr *obj) {
125         int i, first, jump;
126         word am;
127         first = hash_mess(mess);
128         jump = hash_2(first);
129         for (i = first; thisp->hash[i] != 0; ) {
130                 if (hash_check_item(thisp->hash[i], mess)) {
131                         obj->addr=thisp->hash[i];
132                         obj->mark=M[thisp->hash[i] + 1];
133                         return;
134                 }
135                 i = (i + jump) % thisp->hash_size;
136                 if (i == first) {
137                         int *curhash = thisp->hash;
138                         int cursize = thisp->hash_size;
139                         /* the rest is not debugged yet */
140                         errsignal(RTEMEMOV);
141                         thisp->hash_size = cursize * 3 - 1;
142                         thisp->hash = mallocate(thisp->hash_size);
143                         if(thisp->hash == NULL)
144                                 errsignal(RTEMEMOV);
145
146                         for (i = 0; i < thisp->hash_size; i++)
147                                 thisp->hash[i] = 0;
148
149                         for (i = 0; i < cursize; i++) {
150                                 if( curhash[i]!=0 ){
151                                         virtaddr obj;
152                                         procaddr mess;
153                                         obj.addr = curhash[i];
154                                         obj.mark = M[curhash[i] + 1];
155                                         obj2mess(M, &obj, &mess);
156                                         hash_set(&mess, curhash[i]);
157                                 }
158                         }
159                         hash_new_item(obj, mess);
160                         hash_set(mess, obj->addr);
161                         return;
162                 }
163         }
164         /* not exists yet */
165         hash_new_item(obj, mess);
166         thisp->hash[i] = obj->addr;
167 }
168
169 void hash_set(procaddr *mess, word ah) {
170         int i, first, jump;
171         word am;
172         first = hash_mess(mess);
173         jump = hash_2(first);
174         for(i = first; thisp->hash[i] != 0; ) {
175                 assert(!hash_check_item(thisp->hash[i], mess));
176                 i = (i + jump) % thisp->hash_size;
177                 if(i == first)
178                         errsignal(RTEMEMOV);
179         }
180         /* not exists yet */
181         assert(thisp->hash[i] == 0);
182         thisp->hash[i] = ah;
183 }
184
185 #endif
186
187 static int hash_check_item(word ah, procaddr *mess) {
188         word am = M[ah];
189         return (mess->node == M[am + 2] && mess->pix == M[am + 3] &&
190                                                 mess->mark == M[am + 4]);
191 }
192
193 static void hash_new_item(virtaddr *obj, procaddr *mess) {
194         word am;
195         newarry(1, 4, APROCESS, obj, &am);
196         M[am + 2] = mess->node;
197         M[am + 3] = mess->pix;
198         M[am + 4] = mess->mark;
199 }
200
201 static int hash_mess(procaddr *mess) {
202         word hash = mess->pix;
203         hash *= abs(mess->mark);
204         hash += mess->node;
205         return hash % (thisp->hash_size);
206 }
207
208 static int hash_2(int hash_1 ) {
209         return thisp->hash_size -2 - (hash_1 % (thisp->hash_size - 2));
210 }
211