Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / mbk / rcn_cache.c
1 #include AVT_H
2 #include "rcn.h"
3
4 char RCN_DEBUG = 0;
5
6 #define RCN_MAXCACHE 16
7 mbkcache* RCN_POOLCACHE[RCN_MAXCACHE];
8 int RCN_NBCACHE=0;
9
10 /******************************************************************************\
11 Fonction d'accès aux ensembles de cache.
12 \******************************************************************************/
13 mbkcache* rcn_getpoolcache( int pool )
14 {
15 return RCN_POOLCACHE[pool];
16 }
17
18 void rcn_setpoolcache( int pool, mbkcache *cache )
19 {
20 RCN_POOLCACHE[pool] = cache ;
21 }
22
23 int rcn_getnewpoolcache( void )
24 {
25 if( RCN_NBCACHE == RCN_MAXCACHE ) {
26 avt_errmsg( RCN_ERRMSG, "001", AVT_FATAL );
27 }
28 return RCN_NBCACHE++;
29 }
30
31 /******************************************************************************\
32
33 Active le cache pour la lofig. Aucuns réseaux RC ne doit être déjà présent. Si
34 un réseau RC est déjà présent sur un signal, le cache n'est pas actif pour ce
35 signal. Cette fonction est principalement destinée à être utilisée dans les
36 parser.
37
38 \******************************************************************************/
39
40 void rcn_enable_cache( lofig_list *lofig,
41 unsigned long int (*fn_load)(lofig_list*, losig_list*),
42 void (*fn_free)(lofig_list*),
43 int pool
44 )
45 {
46 mbkcache *cache;
47
48 // rcnenv();
49 cache = rcn_getlofigcache( lofig );
50 if( cache || RCN_CACHE_SIZE == 0ul ) return;
51
52 cache = rcn_getpoolcache( pool );
53
54 if( !cache ) {
55 cache = mbk_cache_create(
56 (char(*)(void*,void*))NULL,
57 (unsigned long int(*)(void*,void*))fn_load,
58 (unsigned long int(*)(void*,void*))rcn_cache_release,
59 RCN_CACHE_SIZE
60 );
61 rcn_setpoolcache( pool, cache );
62 }
63
64 rcn_alloclofigcache( lofig, cache, fn_free );
65 }
66
67 /******************************************************************************\
68
69 Libération du cache
70
71 \******************************************************************************/
72
73 void rcn_disable_cache( lofig_list *lofig )
74 {
75 mbkcache *cache;
76 void (*fn_free)(lofig_list*) ;
77 ptype_list *ptl;
78 losig_list *scanlosig;
79
80 cache = rcn_getlofigcache( lofig );
81 if( !cache )
82 return;
83
84 for( scanlosig = lofig->LOSIG ; scanlosig ; scanlosig = scanlosig->NEXT )
85 rcn_flush_signal( lofig, scanlosig );
86
87 ptl = getptype( lofig->USER, RCN_LOFIGCACHE_FREE );
88 if( ptl ) {
89 fn_free = (void(*)(lofig_list*)) ptl->DATA;
90 fn_free( lofig );
91 lofig->USER = delptype( lofig->USER, RCN_LOFIGCACHE_FREE );
92 }
93
94 lofig->USER = delptype( lofig->USER, RCN_LOFIGCACHE );
95 }
96
97 /******************************************************************************\
98
99 Récupère les informations relative au cache pour une lofig. Si cette fonction
100 renvoie NULL, c'est que le cache n'est pas actif pour cette lofig.
101
102 \******************************************************************************/
103
104 mbkcache* rcn_getlofigcache( lofig_list *lofig )
105 {
106 ptype_list *ptl;
107
108 ptl = getptype( lofig->USER, RCN_LOFIGCACHE );
109 if( ptl )
110 return (mbkcache*)(ptl->DATA);
111 return NULL;
112 }
113
114 /******************************************************************************\
115
116 Alloue les informations de cache pour une lofig.
117
118 \******************************************************************************/
119
120 void rcn_alloclofigcache( lofig_list *lofig,
121 mbkcache *cache,
122 void (*fn_free)(lofig_list*)
123 )
124 {
125 lofig->USER = addptype( lofig->USER, RCN_LOFIGCACHE, cache );
126 if( fn_free )
127 lofig->USER = addptype( lofig->USER, RCN_LOFIGCACHE_FREE, fn_free );
128 }
129
130 /******************************************************************************\
131
132 Met à jour un signal. Sans effet si le cache n'est pas actif.
133
134 \******************************************************************************/
135
136 void rcn_refresh_signal( lofig_list *lofig, losig_list *losig )
137 {
138 mbkcache *cache;
139 static lofig_list *lastlofig = NULL;
140 static losig_list *lastlosig = NULL;
141
142 if( lastlofig == lofig && lastlosig == losig )
143 return;
144
145 if( rcn_issignal_disablecache( losig ) ) {
146 // rcn_error( 34, AVT_WARNING );
147 return ;
148 }
149
150 avt_logenterfunction(LOGMBKCACHE,2,"rcn_refresh_signal()" );
151 cache = rcn_getlofigcache( lofig );
152 if( cache ) {
153 rcn_enablewritelofig( lofig );
154 mbk_cache_refresh( cache, lofig, losig );
155 rcn_disablewritelofig( lofig );
156 rcn_setsignal_loaded( losig );
157 lastlofig = lofig;
158 lastlosig = losig;
159
160 rcn_synccapa( lofig, losig );
161 }
162 avt_logexitfunction(LOGMBKCACHE,2);
163
164 // rcn_cache_debug( lofig );
165
166 }
167
168 /******************************************************************************\
169
170 Fonctions de verrouillage d'un signal.
171
172 \******************************************************************************/
173
174 void rcn_lock_signal( lofig_list *lofig, losig_list *losig )
175 {
176 mbkcache *cache;
177
178 cache = rcn_getlofigcache( lofig );
179 if( !cache )
180 return;
181
182 rcn_refresh_signal( lofig, losig );
183 mbk_cache_lock( cache, losig );
184 }
185
186 void rcn_unlock_signal( lofig_list *lofig, losig_list *losig )
187 {
188 mbkcache *cache;
189
190 cache = rcn_getlofigcache( lofig );
191 if( !cache )
192 return;
193
194 mbk_cache_unlock( cache, losig );
195 }
196
197 /* Renvoie YES ou NO */
198 char rcn_islock_signal( lofig_list *lofig, losig_list *losig )
199 {
200 mbkcache *cache;
201
202 cache = rcn_getlofigcache( lofig );
203 if( !cache )
204 return NO;
205
206 return mbk_cache_islock( cache, losig );
207 }
208
209 /******************************************************************************\
210
211 Force la libération des RC d'un signal
212
213 \******************************************************************************/
214
215 void rcn_flush_signal( lofig_list *lofig, losig_list *losig )
216 {
217 mbkcache *cache;
218
219 cache = rcn_getlofigcache( lofig );
220 if( !cache )
221 return;
222
223 mbk_cache_release( cache, lofig, losig );
224 }
225
226 /******************************************************************************\
227
228 Autorise ou interdit les fonctions de modification des vues RCN de la lofig
229
230 \******************************************************************************/
231
232 void rcn_enablewritelofig( lofig_list *lofig )
233 {
234 losig_list *losig;
235 if( RCN_DEBUG ) {
236 for( losig = lofig->LOSIG ; losig ; losig = losig->NEXT )
237 rcn_enblewritesignal( losig );
238 }
239 }
240
241 void rcn_disablewritelofig( lofig_list *lofig )
242 {
243 losig_list *losig;
244 if( RCN_DEBUG ) {
245 for( losig = lofig->LOSIG ; losig ; losig = losig->NEXT )
246 rcn_disablewritesignal( losig );
247 }
248 }
249
250 /******************************************************************************\
251
252 Autorise ou interdit les fonctions de modification des losigs
253
254 \******************************************************************************/
255
256 void rcn_disablewritesignal( losig_list *losig )
257 {
258 if( RCN_DEBUG ) {
259 RCN_SETFLAG( losig->RCNCACHE, RCNCACHEFLAG_WF );
260 }
261 }
262
263 void rcn_enblewritesignal( losig_list *losig )
264 {
265 if( RCN_DEBUG ) {
266 RCN_CLEARFLAG( losig->RCNCACHE, RCNCACHEFLAG_WF );
267 }
268 }
269
270 char rcn_iswritesignal( losig_list *losig )
271 {
272 if( RCN_GETFLAG( losig->RCNCACHE, RCNCACHEFLAG_WF ) )
273 return 0;
274 return 1;
275 }
276
277 void rcn_checkwritesignal( losig_list *losig )
278 {
279 if( RCN_DEBUG ) {
280 if( ! rcn_iswritesignal( losig ) ) {
281 rcn_error( 35, AVT_WARNING );
282 return ;
283 }
284 }
285 }
286
287 /******************************************************************************\
288
289 Indicateurs de l'état d'un signal.
290
291 \******************************************************************************/
292
293 void rcn_setsignal_loaded( losig_list *losig )
294 {
295 RCN_SETFLAG( losig->RCNCACHE, RCNCACHEFLAG_LOAD );
296 }
297
298 void rcn_clearsignal_loaded( losig_list *losig )
299 {
300 RCN_CLEARFLAG( losig->RCNCACHE, RCNCACHEFLAG_LOAD );
301 }
302
303 char rcn_issignal_loaded( losig_list *losig )
304 {
305 if( RCN_GETFLAG( losig->RCNCACHE, RCNCACHEFLAG_LOAD ) )
306 return 1;
307 return 0;
308 }
309
310 void rcn_setsignal_disablecache( losig_list *losig )
311 {
312 RCN_SETFLAG( losig->RCNCACHE, RCNCACHEFLAG_DISABLE );
313 }
314
315 char rcn_issignal_disablecache( losig_list *losig )
316 {
317 if( RCN_GETFLAG( losig->RCNCACHE, RCNCACHEFLAG_DISABLE ) )
318 return 1;
319 return 0;
320 }
321
322 /******************************************************************************\
323
324 Fonction appellée par mbk_cache qui libère le signal.
325
326 \******************************************************************************/
327
328 unsigned long int rcn_cache_release( lofig_list *lofig, losig_list *losig )
329 {
330 chain_list *scanctc;
331 chain_list *nextctc;
332 loctc_list *ptctc;
333 unsigned long int removed=0;
334
335 if (rcn_issignal_disablecache(losig)) return 0;
336
337 rcn_clearsignal_loaded( losig );
338
339 freetable(losig);
340 while( losig->PRCN->PWIRE ) {
341 dellowire( losig,
342 losig->PRCN->PWIRE->NODE1,
343 losig->PRCN->PWIRE->NODE2
344 );
345 removed = removed + RCN_SIZEOFLOWIRE;
346 }
347
348 for( scanctc = losig->PRCN->PCTC ; scanctc ; scanctc = nextctc ) {
349 nextctc = scanctc->NEXT;
350 ptctc = (loctc_list*)(scanctc->DATA);
351 if( rcn_cache_removable_ctc( ptctc ) ) {
352 delloctc( ptctc );
353 removed = removed + RCN_SIZEOFLOCTC;
354 }
355 }
356
357 lofig = NULL; //avoid a warning
358
359 return removed;
360 }
361
362 /******************************************************************************\
363
364 Lors de l'effacement d'une ctc en raison d'un flush du cache, renvoie 1 si la
365 capacité passée en paramètre peut être retirée, et 0 sinon.
366
367 \******************************************************************************/
368
369 char rcn_cache_removable_ctc( loctc_list *ctc )
370 {
371 if( !rcn_issignal_loaded( ctc->SIG1 ) &&
372 !rcn_issignal_loaded( ctc->SIG2 ) )
373 return 1;
374 return 0;
375 }
376
377 /******************************************************************************\
378
379 Lors de l'ajout d'une capacité lors d'un refresh d'un signal, renvoie 1 si il
380 faut ajouter une capacité placée entre les 2 signaux.
381
382 \******************************************************************************/
383
384 char rcn_cache_addable_ctc( losig_list *sig1, losig_list *sig2 )
385 {
386 if( rcn_issignal_loaded( sig1 ) ||
387 rcn_issignal_loaded( sig2 ) )
388 return 0;
389 return 1;
390 }
391
392 /******************************************************************************\
393
394 L'environnement
395
396 \******************************************************************************/
397
398 void rcnenv( void )
399 {
400 char *str, *ptend ;
401
402 str = getenv("RCN_DEBUG");
403
404 if( str ) {
405 if( !strcmp( str, "yes" ) ) {
406 RCN_DEBUG=1;
407 fflush( stdout );
408 fprintf( stderr, "\n*** RCN DEBUG MODE enabled ***.\n" );
409 }
410 else {
411 if( !strcmp( str, "no" ) )
412 RCN_DEBUG=0;
413 else {
414 fflush( stdout );
415 fprintf( stderr, "\n*** warning *** bad value for RCN_DEBUG.\n" );
416 }
417 }
418 }
419 }
420
421 void rcn_cache_debug( lofig_list *lofig )
422 {
423 mbkcache *cache ;
424 losig_list *losig ;
425 unsigned long int size ;
426 chain_list *chain ;
427 lowire_list *wire ;
428 loctc_list *ctc ;
429 mbkcachelist *x;
430 int y ;
431
432 cache = rcn_getlofigcache( lofig );
433 if( !cache )
434 return;
435
436 /* check the cache size */
437
438 size = 0 ;
439
440 for( losig = lofig->LOSIG ; losig ; losig = losig->NEXT ) {
441
442 if( losig->PRCN ) {
443
444 for( wire = losig->PRCN->PWIRE ; wire ; wire = wire->NEXT )
445 size += RCN_SIZEOFLOWIRE ;
446
447 for( chain = losig->PRCN->PCTC ; chain ; chain = chain->NEXT ) {
448 ctc = (loctc_list*)chain->DATA ;
449 if( ctc->SIG1 == losig )
450 size += RCN_SIZEOFLOCTC ;
451 }
452 }
453
454 x = mbk_cache_getmbkcachelist( cache, losig ) ;
455 y = rcn_issignal_loaded( losig ) ;
456
457 if( (x && !y) || (!x && y) )
458 printf( "error : mismatch cache status for signal %p\n", losig );
459
460 }
461
462 if( cache->CURSIZE != size ) {
463 printf( "error : cache->CURSIZE=%lu size=%lu\n", cache->CURSIZE, size );
464 }
465 }
466
467 int rcn_hascache( lofig_list *lofig)
468 {
469 return rcn_getlofigcache( lofig )!=NULL;
470 }