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