Added upstream from http://ftp.icm.edu.pl/pub/loglan/
[loglan.git] / sources / int / procaddr.c
1 #include        "depend.h"\r
2 #include        "genint.h"\r
3 #include        "int.h"\r
4 #include        "process.h"\r
5 #include        "intproto.h"\r
6 \r
7 #include        <assert.h>\r
8 \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
12 \r
13 \r
14 /*\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
22 */\r
23 \r
24 void obj2mess(M,obj,mess)\r
25    word *M;\r
26    virtaddr *obj;\r
27    procaddr *mess;\r
28 {\r
29 #ifdef OBJECTADDR\r
30    word am;\r
31    if( obj->mark != M[obj->addr+1] ){\r
32       mess->node=-1;\r
33       mess->pix =-1;\r
34       mess->mark=-1;\r
35    }else{\r
36       am=M[obj->addr];\r
37       mess->node=M[am+2];\r
38       mess->pix =M[am+3];\r
39       mess->mark=M[am+4];\r
40    }\r
41 #else\r
42    mess->node=ldnode(obj->addr);\r
43    mess->pix =ldpix (obj->addr);\r
44    mess->mark=obj->mark;\r
45 #endif\r
46 }\r
47 \r
48 void mess2obj(p,mess,obj)\r
49    procdescr *p;\r
50    procaddr *mess;\r
51    virtaddr *obj;\r
52 {\r
53 \r
54 #ifdef OBJECTADDR\r
55 \r
56    word am;\r
57    word *currM=M;\r
58    word currpix=thispix;\r
59 \r
60    extern int compactify_allowed;\r
61    compactify_allowed=0;\r
62 \r
63    transfer(p-process);\r
64 \r
65    hash_find(mess,obj);\r
66 /*\r
67    newarry(1,4,APROCESS,obj,&am);\r
68    M[am+2]=mess->node;\r
69    M[am+3]=mess->pix;\r
70    M[am+4]=mess->mark;\r
71 */\r
72 \r
73    transfer(currpix);\r
74    M=currM;\r
75 \r
76    compactify_allowed=1;\r
77 \r
78 #else\r
79 \r
80    obj->addr=staddr(mess->node,mess->pix);\r
81    obj->mark=mess->mark;\r
82 \r
83 #endif\r
84 \r
85 }\r
86 \r
87 \r
88 \r
89 bool isprocess(v) virtaddr *v; {\r
90 \r
91 #ifdef OBJECTADDR\r
92 \r
93    word am=M[v->addr];\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
97 \r
98 #else\r
99 \r
100    return ( v->mark < 0 );\r
101 \r
102 #endif\r
103 \r
104 }\r
105 \r
106 \r
107 \r
108 #ifdef OBJECTADDR\r
109 \r
110 /* hash entry is a word pointing to dictionary or 0 if empty */\r
111 \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
117 #else\r
118 static int hash_check_item();\r
119 static void hash_new_item();\r
120 #endif\r
121 \r
122 void hash_create(p,size) procdescr *p; int size;{\r
123    /* create hash table for p process */\r
124    int i;\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
130 }\r
131 \r
132 \r
133 /* find pointer in hash table, add if not exists */\r
134 \r
135 void hash_find(mess,obj) procaddr *mess; virtaddr *obj; {\r
136    int i,first,jump;\r
137    word am;\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
144          return;\r
145       }\r
146       i=(i+jump)%thisp->hash_size;\r
147       if( i==first ){\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
157                virtaddr obj;\r
158                procaddr mess;\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
163             }\r
164          }\r
165          hash_new_item( obj, mess );\r
166          hash_set( mess, obj->addr );\r
167          return;\r
168       }\r
169    }\r
170    /* not exists yet */\r
171    hash_new_item( obj, mess );\r
172    thisp->hash[i]=obj->addr;\r
173 }\r
174 \r
175 void hash_set(mess,ah) procaddr *mess; word ah;{\r
176    int i,first,jump;\r
177    word am;\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
184    }\r
185    /* not exists yet */\r
186    assert( thisp->hash[i]==0 );\r
187    thisp->hash[i]=ah;\r
188 }\r
189 \r
190 #endif\r
191 \r
192 \r
193 static int hash_check_item( ah, mess )  word ah; procaddr *mess; {\r
194    word am=M[ah];\r
195    return ( mess->node==M[am+2] && mess->pix==M[am+3] && mess->mark==M[am+4] );\r
196 }\r
197 \r
198 static void hash_new_item( obj, mess )  virtaddr *obj; procaddr *mess; {\r
199    word am;\r
200    newarry(1,4,APROCESS,obj,&am);\r
201    M[am+2]=mess->node;\r
202    M[am+3]=mess->pix;\r
203    M[am+4]=mess->mark;\r
204 }\r
205 \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
211 }\r
212 \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
215 }\r
216 \r