5 #include "intproto.h"
\r
9 #define ldnode(addr) ((word) (addr & 0xFF))
\r
10 #define ldpix(addr) ((word) ((addr >> 8) & 0xFF))
\r
11 #define staddr(node, pix) ((word) ((pix << 8) | node))
\r
15 These are converters from global to process pointers in memory
\r
16 to global process pointers in message.
\r
17 M denotes memory in which pair (pointer,object) exists or has to exist.
\r
18 We want to create object denoting remote process instead of
\r
19 dummy pointer without object.
\r
20 The object will be like an arrayof integer of size 2.
\r
21 arr[1..3] : arr[1]=node, arr[2]=pix.
\r
24 void obj2mess(M,obj,mess)
\r
31 if( obj->mark != M[obj->addr+1] ){
\r
42 mess->node=ldnode(obj->addr);
\r
43 mess->pix =ldpix (obj->addr);
\r
44 mess->mark=obj->mark;
\r
48 void mess2obj(p,mess,obj)
\r
58 word currpix=thispix;
\r
60 extern int compactify_allowed;
\r
61 compactify_allowed=0;
\r
63 transfer(p-process);
\r
65 hash_find(mess,obj);
\r
67 newarry(1,4,APROCESS,obj,&am);
\r
76 compactify_allowed=1;
\r
80 obj->addr=staddr(mess->node,mess->pix);
\r
81 obj->mark=mess->mark;
\r
89 bool isprocess(v) virtaddr *v; {
\r
94 /* assert(v->mark<=M[v->addr+1]);*/
\r
95 if( v->mark!=M[v->addr+1] ) return 0;
\r
96 else return ( M[am+1]==APROCESS );
\r
100 return ( v->mark < 0 );
\r
110 /* hash entry is a word pointing to dictionary or 0 if empty */
\r
112 #ifndef NO_PROTOTYPES
\r
113 static int hash_check_item( word, procaddr * );
\r
114 static void hash_new_item( virtaddr *, procaddr * );
\r
115 static int hash_mess( procaddr * );
\r
116 static int hash_2( int );
\r
118 static int hash_check_item();
\r
119 static void hash_new_item();
\r
122 void hash_create(p,size) procdescr *p; int size;{
\r
123 /* create hash table for p process */
\r
125 if( p->hash!=NULL ) free( p->hash );
\r
126 p->hash_size = size;
\r
127 p->hash = mallocate(size);
\r
128 if( p->hash==NULL ) errsignal(RTEMEMOV);
\r
129 for( i=0; i<p->hash_size; i++ ) p->hash[i]=0;
\r
133 /* find pointer in hash table, add if not exists */
\r
135 void hash_find(mess,obj) procaddr *mess; virtaddr *obj; {
\r
138 first=hash_mess( mess );
\r
139 jump=hash_2(first);
\r
140 for( i=first; thisp->hash[i]!=0; ){
\r
141 if( hash_check_item(thisp->hash[i],mess) ){
\r
142 obj->addr=thisp->hash[i];
\r
143 obj->mark=M[thisp->hash[i]+1];
\r
146 i=(i+jump)%thisp->hash_size;
\r
148 int *curhash=thisp->hash;
\r
149 int cursize=thisp->hash_size;
\r
150 errsignal(RTEMEMOV); /* the rest is not debugged yet */
\r
151 thisp->hash_size = cursize*3-1;
\r
152 thisp->hash = mallocate(thisp->hash_size);
\r
153 if( thisp->hash==NULL ) errsignal(RTEMEMOV);
\r
154 for( i=0; i<thisp->hash_size; i++ ) thisp->hash[i]=0;
\r
155 for( i=0; i<cursize; i++ ){
\r
156 if( curhash[i]!=0 ){
\r
159 obj.addr=curhash[i];
\r
160 obj.mark=M[curhash[i]+1];
\r
161 obj2mess(M,&obj,&mess);
\r
162 hash_set(&mess,curhash[i]);
\r
165 hash_new_item( obj, mess );
\r
166 hash_set( mess, obj->addr );
\r
170 /* not exists yet */
\r
171 hash_new_item( obj, mess );
\r
172 thisp->hash[i]=obj->addr;
\r
175 void hash_set(mess,ah) procaddr *mess; word ah;{
\r
178 first=hash_mess( mess );
\r
179 jump=hash_2(first);
\r
180 for( i=first; thisp->hash[i]!=0; ){
\r
181 assert( !hash_check_item(thisp->hash[i],mess) );
\r
182 i=(i+jump)%thisp->hash_size;
\r
183 if( i==first ) errsignal(RTEMEMOV);
\r
185 /* not exists yet */
\r
186 assert( thisp->hash[i]==0 );
\r
193 static int hash_check_item( ah, mess ) word ah; procaddr *mess; {
\r
195 return ( mess->node==M[am+2] && mess->pix==M[am+3] && mess->mark==M[am+4] );
\r
198 static void hash_new_item( obj, mess ) virtaddr *obj; procaddr *mess; {
\r
200 newarry(1,4,APROCESS,obj,&am);
\r
201 M[am+2]=mess->node;
\r
203 M[am+4]=mess->mark;
\r
206 static int hash_mess( mess ) procaddr *mess;{
\r
207 word hash=mess->pix;
\r
208 hash *= abs( mess->mark );
\r
209 hash += mess->node;
\r
210 return hash % (thisp->hash_size);
\r
213 static int hash_2( hash_1 ) int hash_1;{
\r
214 return thisp->hash_size -2 - ( hash_1 % ( thisp->hash_size -2 ) );
\r