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