1 /*****************************************************************************
2   FILE           : $Source: /projects/higgs1/SNNS/CVS/SNNS/kernel/sources/kr_mem.c,v $
3   SHORTNAME      :
4   SNNS VERSION   : 4.2
5 
6   PURPOSE        : SNNS-Kernel Memory Manager
7   NOTES          :
8 
9   AUTHOR         : Niels Mache
10   DATE           : 21.2.90
11 
12   CHANGED BY     : Sven Doering
13   RCS VERSION    : $Revision: 2.17 $
14   LAST CHANGE    : $Date: 1998/05/15 13:12:08 $
15 
16     Copyright (c) 1990-1995  SNNS Group, IPVR, Univ. Stuttgart, FRG
17     Copyright (c) 1996-1998  SNNS Group, WSI, Univ. Tuebingen, FRG
18 
19 ******************************************************************************/
20 #include <config.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <memory.h>
25 #ifdef HAVE_VALUES_H
26 #include <values.h>
27 #else
28 #include <math.h>
29 #include <limits.h>
30 #endif
31 #include <limits.h>
32 
33 #include "kr_typ.h"	 /*  Kernel Types and Constants  */
34 #include "kernel.h"
35 #include "kr_const.h"	 /*  Constant Declarators for SNNS-Kernel  */
36 #include "kr_def.h"	 /*  Default Values  */
37 
38 #include "kr_mem.ph"	 /*  Function prototypes  */
39 #include "kr_mac.h"	 /*  Kernel Macros  */
40 
41 
42 #ifndef MAXSHORT
43 #define MAXSHORT SHRT_MAX
44 #endif
45 
46 /*  ULTRIX-32 Operating System	*/
47 #if defined (ultrix) || defined (__BORLANDC__)
48 #include "strdup.h"	/*  include strdup function because strdup is
49 			    missing in ULTRIX-32  */
50 #endif
51 
52 
53 /*****************************************************************************
54   FUNCTION : krm_allocLinks
55 
56   PURPOSE  : allocate another link array (with size N entries)
57   NOTES    :
58 
59   RETURNS  :
60   UPDATE   :
61 ******************************************************************************/
krm_allocLinks(int N)62 static  int     krm_allocLinks(int N)
63 {
64   LinkArray     tmp_ptr;
65 
66 
67   tmp_ptr = (LinkArray) calloc((unsigned int)( N + 1), LINK_SIZE );
68   if (tmp_ptr == NULL)  return( 1 );
69 
70   if (link_array == NULL)
71     {
72     tmp_ptr->next = NULL;           /*  free link/block sentinel
73                                     */
74     free_link_ptr = tmp_ptr;
75     }
76   else
77     {
78     tmp_ptr->next = link_block_list;
79     }
80 
81   link_block_list = tmp_ptr;    /* free link block sentinel */
82   NoOfAllocLinks += N;
83   link_array = tmp_ptr;         /* link_array points to the first link entry */
84   return( 0 );
85 }
86 
87 
88 /*****************************************************************************
89   FUNCTION : krm_getLink
90 
91   PURPOSE  : get one link structure
92   NOTES    :
93 
94   RETURNS  :
95   UPDATE   :
96 ******************************************************************************/
krm_getLink(void)97 struct Link  *krm_getLink(void)
98 {
99   struct Link   *tmp_ptr;
100 
101 
102   if ((NoOfLinks == NoOfAllocLinks) || (link_array == NULL))
103     if (krm_allocLinks( LINK_BLOCK ) != 0)
104       {  /*  memory allocation failed  */
105       KernelErrorCode = KRERR_INSUFFICIENT_MEM;
106       return( NULL );
107     }
108 
109   NoOfLinks++;
110 
111   if (free_link_ptr->next != NULL)
112     {
113     tmp_ptr = free_link_ptr;
114     free_link_ptr = free_link_ptr->next;
115   }
116   else
117     {
118     tmp_ptr = ++link_array;
119   }
120 
121   return( tmp_ptr );
122 }
123 
124 
125 /*****************************************************************************
126   FUNCTION : krm_releaseLink
127 
128   PURPOSE  : release one link structure
129   NOTES    :
130 
131   RETURNS  :
132   UPDATE   :
133 ******************************************************************************/
krm_releaseLink(struct Link * link_ptr)134 void    krm_releaseLink(struct Link *link_ptr)
135 {
136   --NoOfLinks;
137 
138   link_ptr->next = free_link_ptr;
139   free_link_ptr  = link_ptr;
140 }
141 
142 
143 /*****************************************************************************
144   FUNCTION : krm_releaseAllLinks
145 
146   PURPOSE  : release the link and all following links
147   NOTES    :
148 
149   RETURNS  :
150   UPDATE   :
151 ******************************************************************************/
krm_releaseAllLinks(struct Link * first_link_ptr)152 void    krm_releaseAllLinks(struct Link *first_link_ptr)
153 {
154   struct Link  *curr,
155                *next,
156                *free;
157 
158 
159   free = free_link_ptr;
160   curr = first_link_ptr;
161 
162   while (curr != NULL)  {
163     --NoOfLinks;
164 
165     next = curr->next;
166     curr->next = free;
167 
168     free = curr;
169     curr = next;
170   }
171 
172   free_link_ptr = free;
173 }
174 
175 
176 /*****************************************************************************
177   FUNCTION : krm_releaseLinkArrays
178 
179   PURPOSE  : free all link array
180   NOTES    :
181 
182   RETURNS  :
183   UPDATE   :
184 ******************************************************************************/
krm_releaseLinkArrays(void)185 void  krm_releaseLinkArrays(void)
186 {
187   register struct Link  *tmp_ptr1, *tmp_ptr2;
188 
189 
190   NoOfLinks = NoOfAllocLinks = 0;
191 
192   if (link_array != NULL)  {
193     tmp_ptr2 = link_block_list;
194     while (tmp_ptr2 != NULL)  {
195       tmp_ptr1 = tmp_ptr2->next;
196       free( (char *) tmp_ptr2 );
197       tmp_ptr2 = tmp_ptr1;
198     }
199 
200     free_link_ptr = link_array = NULL;
201   }
202 }
203 
204 
205 
206 /*#################################################
207 
208 GROUP: Site Functions
209 
210 #################################################*/
211 /*****************************************************************************
212   FUNCTION : krm_allocSites
213 
214   PURPOSE  : allocate another site array (with size N entries)
215   NOTES    :
216 
217   RETURNS  :
218   UPDATE   :
219 ******************************************************************************/
krm_allocSites(int N)220 static  int     krm_allocSites(int N)
221 {
222   SiteArray     tmp_ptr;
223 
224 
225   tmp_ptr = (SiteArray) calloc((unsigned int)(N + 1), SITE_SIZE );
226   if (tmp_ptr == NULL)  return( 1 );
227 
228   if (site_array == NULL)  {
229     tmp_ptr->next = NULL;           /*  free site/block sentinel   */
230     free_site_ptr = tmp_ptr;
231   }
232   else  {
233     tmp_ptr->next = site_block_list;
234   }
235 
236   site_block_list = tmp_ptr;    /*  free site block sentinel  */
237   NoOfAllocSites += N;
238   site_array = tmp_ptr;         /*  site_array points to the sentinel */
239   return( 0 );
240 }
241 
242 
243 /*****************************************************************************
244   FUNCTION : krm_getSite
245 
246   PURPOSE  : get one unit-site structure
247   NOTES    :
248 
249   RETURNS  :
250   UPDATE   :
251 ******************************************************************************/
krm_getSite(void)252 struct Site    *krm_getSite(void)
253 {
254   struct Site   *tmp_ptr;
255 
256 
257   if ((site_array == NULL) || (NoOfSites == NoOfAllocSites))
258     if (krm_allocSites( SITE_BLOCK ) != 0)  {
259       KernelErrorCode = KRERR_INSUFFICIENT_MEM;
260       return( NULL );
261     }
262 
263   NoOfSites++;
264   NoOfNetSites++;
265 
266   if (free_site_ptr->next != NULL)  {
267     tmp_ptr = free_site_ptr;
268     free_site_ptr = free_site_ptr->next;
269   }
270   else  {
271     tmp_ptr = ++site_array;
272   }
273 
274   return( tmp_ptr );
275 }
276 
277 
278 /*****************************************************************************
279   FUNCTION : krm_getFtypeSite
280 
281   PURPOSE  : get one site structure for functionality use only
282   NOTES    :
283 
284   RETURNS  :
285   UPDATE   :
286 ******************************************************************************/
krm_getFtypeSite(void)287 static struct Site  *krm_getFtypeSite(void)
288 {
289   struct Site  *tmp_ptr;
290 
291   KernelErrorCode = KRERR_NO_ERROR;
292 
293   if ((site_array == NULL) || (NoOfSites == NoOfAllocSites))
294     if (krm_allocSites( SITE_BLOCK ) != 0)  {
295       KernelErrorCode = KRERR_INSUFFICIENT_MEM;
296       return( NULL );
297     }
298 
299   NoOfSites++;
300 
301   if (free_site_ptr->next != NULL)  {
302     tmp_ptr = free_site_ptr;
303     free_site_ptr = free_site_ptr->next;
304   }
305   else  {
306     tmp_ptr = ++site_array;
307   }
308 
309   return( tmp_ptr );
310 }
311 
312 
313 /*****************************************************************************
314   FUNCTION : krm_releaseSite
315 
316   PURPOSE  : release one unit-site structure
317   NOTES    :
318 
319   RETURNS  :
320   UPDATE   :
321 ******************************************************************************/
krm_releaseSite(struct Site * site_ptr)322 void    krm_releaseSite(struct Site *site_ptr)
323 {
324   --NoOfSites;
325   --NoOfNetSites;
326 
327   site_ptr->next = free_site_ptr;
328   free_site_ptr  = site_ptr;
329 }
330 
331 
332 /*****************************************************************************
333   FUNCTION :krm_releaseFtypeSite
334 
335   PURPOSE  :
336   NOTES    : Future Use:
337              release one Ftype-site structure
338 
339   RETURNS  :
340   UPDATE   :
341 ******************************************************************************/
342 /*
343 static void    krm_releaseFtypeSite(struct Site *site_ptr )
344 {
345   --NoOfSites;
346 
347   site_ptr->next = free_site_ptr;
348   free_site_ptr  = site_ptr;
349 }
350 */
351 
352 /*****************************************************************************
353   FUNCTION : krm_releaseAllSites
354 
355   PURPOSE  : release the unit-site and all following sites (at this unit)
356   NOTES    :
357 
358   RETURNS  :
359   UPDATE   :
360 ******************************************************************************/
krm_releaseAllSites(struct Site * first_site_ptr)361 void    krm_releaseAllSites(struct Site *first_site_ptr)
362 {
363   struct Site  *curr,
364                *next,
365                *free;
366 
367 
368   free = free_site_ptr;
369   curr = first_site_ptr;
370 
371   while (curr != NULL)  {
372     --NoOfSites;
373     --NoOfNetSites;
374 
375     next = curr->next;
376     curr->next = free;
377 
378     free = curr;
379     curr = next;
380   }
381 
382   free_site_ptr = free;
383 }
384 
385 
386 /*****************************************************************************
387   FUNCTION : krm_releaseAllFtypeSites
388 
389   PURPOSE  : release the Ftype-site and all following sites
390   NOTES    :
391 
392   RETURNS  :
393   UPDATE   :
394 ******************************************************************************/
krm_releaseAllFtypeSites(struct Site * first_site_ptr)395 static void    krm_releaseAllFtypeSites(struct Site *first_site_ptr)
396 {
397   struct Site  *curr,
398                *next,
399                *free;
400 
401 
402   free = free_site_ptr;
403   curr = first_site_ptr;
404 
405   while (curr != NULL)  {
406     --NoOfSites;
407 
408     next = curr->next;
409     curr->next = free;
410 
411     free = curr;
412     curr = next;
413   }
414 
415   free_site_ptr = free;
416 }
417 
418 /*****************************************************************************
419   FUNCTION :  krm_releaseSiteArrays
420 
421   PURPOSE  : free all site arrays
422   NOTES    :
423 
424   RETURNS  :
425   UPDATE   :
426 ******************************************************************************/
krm_releaseSiteArrays(void)427 static  void    krm_releaseSiteArrays(void)
428 {
429   struct Site      *tmp_ptr;
430 
431 
432   NoOfSites      = 0;
433   NoOfNetSites   = 0;
434   NoOfAllocSites = 0;
435 
436   if (site_array != NULL)  {
437     while (site_block_list != NULL)  {
438       tmp_ptr =  site_block_list->next;
439       free( (char *) site_block_list );
440       site_block_list = tmp_ptr;
441     }
442 
443     free_site_ptr = NULL;
444     site_array    = NULL;
445   }
446 }
447 
448 
449 
450 /*#################################################
451 
452 GROUP: Unit Functions
453 
454 #################################################*/
455 /*****************************************************************************
456   FUNCTION : krm_unitArrayGC
457 
458   PURPOSE  : garbage collection of unit array
459   NOTES    :
460 
461   RETURNS  :
462   UPDATE   :
463 ******************************************************************************/
krm_unitArrayGC(void)464 void  krm_unitArrayGC(void)
465 {
466   register struct Link   *link_ptr;
467   register struct Site   *site_ptr;
468   register struct Unit   *unit_ptr;
469   register struct Unit   *new_unit_ptr;
470   struct Unit   *dest_unit_ptr;
471 
472 
473   /*  find first unused unit stucture  */
474   dest_unit_ptr = NULL;
475   FOR_ALL_UNITS( unit_ptr )
476     if (!UNIT_IN_USE( unit_ptr ))
477       {  /*  unit isn't in use  */
478       dest_unit_ptr = unit_ptr;  /*  store the first unused unit stucture  */
479       break;
480     }
481 
482   if (dest_unit_ptr != NULL)
483     {  /*  do garbage collection  */
484     NetModified = TRUE;
485 
486     /*  store continous unit pointers in each unit struct  */
487     new_unit_ptr = unit_array;
488     FOR_ALL_UNITS( unit_ptr )
489       if UNIT_IN_USE( unit_ptr )
490         /*  unit is in use  */
491         unit_ptr->Aux.ptr = (char *) ++new_unit_ptr;
492 
493     /*  adjust the link pointers  */
494     FOR_ALL_UNITS( unit_ptr )
495       if UNIT_IN_USE( unit_ptr )  {
496 	if UNIT_HAS_SITES( unit_ptr )
497 	  FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )
498               link_ptr->to = (struct Unit *) link_ptr->to->Aux.ptr;
499         else
500 	  if UNIT_HAS_DIRECT_INPUTS( unit_ptr )
501 	    FOR_ALL_LINKS( unit_ptr, link_ptr )
502               link_ptr->to = (struct Unit *) link_ptr->to->Aux.ptr;
503       }
504 
505 
506     /*  compress unit array  */
507     for (unit_ptr = dest_unit_ptr+1; unit_ptr<=unit_array+MaxUnitNo; unit_ptr++)
508       if UNIT_IN_USE( unit_ptr )
509         memcpy( (char *) dest_unit_ptr++, (char *) unit_ptr, UNIT_SIZE );
510 
511     MinUnitNo = 1;
512     MaxUnitNo = NoOfUnits;
513     FreeUnitIndex = 0;
514   }
515 
516   /*  reduce size of unit array, if needed  */
517   if ((NoOfAllocUnits - NoOfUnits) >= (2 * UNIT_BLOCK))  {
518     unit_ptr = (UnitArray) realloc( (char *) unit_array, (unsigned)
519                                    ((NoOfAllocUnits + 1 - UNIT_BLOCK) *
520 				    UNIT_SIZE) );
521     if (unit_ptr != NULL)  {
522       unit_array = unit_ptr;
523       NoOfAllocUnits -= UNIT_BLOCK;
524     }
525   }
526 }
527 
528 
529 /*****************************************************************************
530   FUNCTION : krm_relocateLinkPtrs
531 
532   PURPOSE  : relocate the link pointers. (If the address of the unit array was modified
533              because the memory was reallocated, the link pointers must be relocated)
534 
535   NOTES    :
536 
537   RETURNS  :
538   UPDATE   :
539 ******************************************************************************/
krm_relocateLinkPtrs(int offset)540 static  void    krm_relocateLinkPtrs(int offset)
541 {
542   register struct Link   *link_ptr;
543   register struct Site   *site_ptr;
544   register struct Unit   *unit_ptr;
545 
546 
547   FOR_ALL_UNITS( unit_ptr )
548     if UNIT_IN_USE( unit_ptr )  {
549       if UNIT_HAS_SITES( unit_ptr )
550 	FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )
551 	  link_ptr->to = (struct Unit *) ((char *) link_ptr->to + offset);
552       else
553 	if UNIT_HAS_DIRECT_INPUTS( unit_ptr )
554 	  FOR_ALL_LINKS( unit_ptr, link_ptr )
555             link_ptr->to = (struct Unit *) ((char *) link_ptr->to + offset);
556     }
557 }
558 
559 
560 /*****************************************************************************
561   FUNCTION : krm_allocUnits
562 
563   PURPOSE  : allocate the unit array
564   NOTES    :
565 
566   RETURNS  :
567   UPDATE   :
568 ******************************************************************************/
krm_allocUnits(int N)569 krui_err  krm_allocUnits(int N)
570 {
571   UnitArray  tmp_ptr;
572   int  offset;
573 
574   if ((NoOfAllocUnits - NoOfUnits) < N)
575     {  /*  alloc units	*/
576     N = (N / UNIT_BLOCK + 1) * UNIT_BLOCK;
577   }
578 
579   if (unit_array == NULL)  {
580     tmp_ptr = (UnitArray) calloc((unsigned int)( NoOfAllocUnits + N + 1 ),
581 				 UNIT_SIZE );
582     if (tmp_ptr == NULL)
583       {  /*  mem alloc failed	 */
584       KernelErrorCode = KRERR_INSUFFICIENT_MEM;
585       return( KernelErrorCode );
586     }
587     FreeUnitIndex = 0;
588     tmp_ptr[0].Out.nextFreeUnit = 0;   /*  sentinel of free unit list
589                                        */
590   }
591   else  {
592     tmp_ptr = (UnitArray) realloc( (char *) unit_array, (unsigned)
593                                    ((NoOfAllocUnits + N + 1 ) * UNIT_SIZE) );
594     if (tmp_ptr == NULL)
595       {  /*  mem alloc failed	 */
596       KernelErrorCode = KRERR_INSUFFICIENT_MEM;
597       return( KernelErrorCode );
598     }
599     offset = (char *) tmp_ptr - (char *) unit_array;
600     if (offset != 0)  krm_relocateLinkPtrs( offset );
601   }
602 
603   NoOfAllocUnits += N;
604   unit_array = tmp_ptr;
605 
606   KernelErrorCode = KRERR_NO_ERROR;
607   return( KernelErrorCode );
608 }
609 
610 /*****************************************************************************
611   FUNCTION : krm_getUnit
612 
613   PURPOSE  : get one unit structure
614   NOTES    :
615 
616   RETURNS  : the number of the current unit structure. This number is negative
617              if a new block had to be allocated, to signal the calling program
618              that it has to update its unit pointers.
619   UPDATE   :
620 ******************************************************************************/
krm_getUnit(void)621 int  krm_getUnit(void)
622 {
623   register int   unit_no;
624   int ret_fact = 1;
625 
626   KernelErrorCode = KRERR_NO_ERROR;
627   if ((unit_array == NULL) || (NoOfUnits == NoOfAllocUnits)){
628     if (krm_allocUnits( UNIT_BLOCK ) != 0)
629       {  /*  Insufficient memory  */
630       KernelErrorCode = KRERR_INSUFFICIENT_MEM;
631       return( 0 );
632     }
633     ret_fact = -1;
634   }
635   NoOfUnits++;
636 
637   if (FreeUnitIndex != 0)
638     {  /*  reuse unit  */
639     unit_no = FreeUnitIndex;
640     FreeUnitIndex = unit_array[unit_no].Out.nextFreeUnit;
641   }
642   else
643     unit_no = NoOfUnits;
644 
645   /*  this unit is ready to use  */
646   unit_array[unit_no].flags = UFLAG_IN_USE;
647   unit_array[unit_no].sites = NULL;
648 
649   if (NoOfUnits == 1)
650     MinUnitNo = MaxUnitNo = unit_no;
651   else  {
652     /*	store the highest allocated unit number  */
653     if (unit_no > MaxUnitNo)  MaxUnitNo = unit_no;
654     /*	store the lowest allocated unit number	*/
655     if (unit_no < MinUnitNo)  MinUnitNo = unit_no;
656   }
657 
658   return( unit_no * ret_fact);
659 }
660 
661 
662 /*****************************************************************************
663   FUNCTION : krm_releaseUnit
664 
665   PURPOSE  : release unit
666 
667   NOTES    : NEW VERSION in SNNS V3.0
668              Now the garbage collection is performed on every deletion of
669              a unit.
670 
671   RETURNS  :
672   UPDATE   :
673 ******************************************************************************/
krm_releaseUnit(int UnitNo)674 void    krm_releaseUnit(int UnitNo)
675 {
676   if (unit_array[UnitNo].flags != UFLAG_FREE) {  /*  don't release twice
677                                                  */
678     --NoOfUnits;
679 
680     unit_array[UnitNo].flags = UFLAG_FREE;
681 
682   }
683 }
684 
685 
686 /*****************************************************************************
687   FUNCTION : krm_releaseUnitArrays
688 
689   PURPOSE  : free the unit array
690   NOTES    :
691 
692   RETURNS  :
693   UPDATE   :
694 ******************************************************************************/
krm_releaseUnitArrays(void)695 static	void	krm_releaseUnitArrays(void)
696 {
697   NoOfAllocUnits = FreeUnitIndex =
698   NoOfUnits = NoOfInputUnits = NoOfOutputUnits =
699   NoOfHiddenUnits = MaxUnitNo = 0;
700 
701   if (unit_array != NULL)  {
702     free( (char *) unit_array );
703     unit_array = NULL;
704   }
705 }
706 
707 
708 
709 /*#################################################
710 
711 GROUP: General Purpose Functions
712 
713 #################################################*/
714 /*****************************************************************************
715   FUNCTION : krm_getMemoryManagerInfo
716 
717   PURPOSE  : get information about memory usage
718   NOTES    :
719 
720   RETURNS  :
721   UPDATE   :
722 ******************************************************************************/
krm_getMemoryManagerInfo(int * array_size,int info_array[])723 void    krm_getMemoryManagerInfo(int *array_size, int info_array[])
724 {
725   info_array[ 0 ] = NoOfNetSites;
726 
727 #ifdef MASPAR_KERNEL
728   if (specialNetworkType == NET_TYPE_FF1)
729     info_array[ 1 ] = descrFFnet.no_of_weights;
730   else
731     info_array[ 1 ] = NoOfLinks;
732 #else
733   info_array[ 1 ] = NoOfLinks;
734 #endif
735 
736   info_array[ 2 ] = NoOfSTableEntries;
737   info_array[ 3 ] = NoOfFTableEntries;
738 
739   info_array[ 4 ] = NoOfAllocUnits;
740   info_array[ 5 ] = NoOfAllocSites;
741   info_array[ 6 ] = NoOfAllocLinks;
742   info_array[ 7 ] = NoOfAllocNTableEntries;
743   info_array[ 8 ] = NoOfAllocSTableEntries;
744   info_array[ 9 ] = NoOfFTableEntries;
745 
746   *array_size = 10;
747 }
748 
749 
750 /*****************************************************************************
751   FUNCTION : krm_allocUnitTopoArray
752 
753   PURPOSE  : allocate the array for topological sorting of the units in the
754              network
755   NOTES    :
756 
757   RETURNS  :
758   UPDATE   :
759 ******************************************************************************/
krm_allocUnitTopoArray(int N)760 krui_err  krm_allocUnitTopoArray(int N)
761 {
762   KernelErrorCode = KRERR_NO_ERROR;  /*  reset return code  */
763 
764   if (topo_ptr_array != NULL)
765     {  /*  reallocate array for topologic sorting  */
766     topo_ptr_array = (TopoPtrArray) realloc( (char *) topo_ptr_array,
767 					     (unsigned) (N * TOPO_PTR_SIZE) );
768   }
769   else
770     {  /*  allocate new array for topologic sorting  */
771     topo_ptr_array = (TopoPtrArray) calloc((unsigned int) N, TOPO_PTR_SIZE);
772   }
773 
774   if (topo_ptr_array == NULL)  KernelErrorCode = KRERR_INSUFFICIENT_MEM;
775 
776   return( KernelErrorCode );
777 }
778 
779 
780 /*****************************************************************************
781   FUNCTION : krm_releaseUnitTopoArray
782 
783   PURPOSE  : release the topolocic array
784   NOTES    :
785 
786   RETURNS  :
787   UPDATE   :
788 ******************************************************************************/
krm_releaseUnitTopoArray(void)789 void  krm_releaseUnitTopoArray(void)
790 {
791   if (topo_ptr_array != NULL)  {
792     free( (char *) topo_ptr_array );
793     topo_ptr_array = NULL;
794   }
795 }
796 
797 
798 
799 /*#################################################
800 
801 GROUP: NameTable Functions
802 
803 #################################################*/
804 /*****************************************************************************
805   FUNCTION : krm_allocNTableArray
806 
807   PURPOSE  : allocate one name-table block
808   NOTES    :
809 
810   RETURNS  :
811   UPDATE   :
812 ******************************************************************************/
krm_allocNTableArray(void)813 static  int     krm_allocNTableArray(void)
814 {
815   NTableArray     tmp_ptr;
816 
817 
818   tmp_ptr = (NTableArray) calloc( NTABLE_BLOCK + 1, NTABLE_SIZE );
819   if (tmp_ptr == NULL)  return( 1 );
820 
821   if (NTable_array == NULL)  {
822     tmp_ptr->Entry.next = NULL;     /*  free name-table block sentinel  */
823     free_NTable_entry = tmp_ptr;    /*  free name-table entry sentinel  */
824   }
825   else  {
826     tmp_ptr->Entry.next = NTable_block_list;    /*  append new name-table block
827                                                     to block list   */
828   }
829 
830   NTable_block_list = tmp_ptr;      /* update block list ptr */
831   NoOfAllocNTableEntries += NTABLE_BLOCK;
832   NTable_array = tmp_ptr + 1;       /* NTable_array points to the first entry */
833   return( 0 );
834 }
835 
836 
837 /*****************************************************************************
838   FUNCTION : krm_getNTableEntry
839 
840   PURPOSE  : get one name-table entry
841   NOTES    :
842 
843   RETURNS  :
844   UPDATE   :
845 ******************************************************************************/
krm_getNTableEntry(void)846 static struct NameTable  *krm_getNTableEntry(void)
847 {
848   struct NameTable  *tmp_ptr;
849 
850 
851   if ((NTable_array == NULL) || (NoOfNTableEntries == NoOfAllocNTableEntries))
852     if (krm_allocNTableArray() != 0)  {
853       KernelErrorCode = KRERR_INSUFFICIENT_MEM;
854       return( NULL );
855     }
856 
857   NoOfNTableEntries++;
858 
859   if (free_NTable_entry->Entry.next != NULL)
860     {   /*  a previous released name-table entry is availabe    */
861     tmp_ptr = free_NTable_entry;
862     free_NTable_entry = free_NTable_entry->Entry.next;
863   }
864   else  {
865     tmp_ptr = NTable_array++;
866   }
867 
868   KernelErrorCode = KRERR_NO_ERROR;
869   tmp_ptr->ref_count = 1;
870   return( tmp_ptr );
871 }
872 
873 
874 /*****************************************************************************
875   FUNCTION : krm_NTableReleaseEntry
876 
877   PURPOSE  : release one name-table entry
878   NOTES    :
879 
880   RETURNS  :
881   UPDATE   :
882 ******************************************************************************/
krm_NTableReleaseEntry(struct NameTable * NTable_ptr)883 void    krm_NTableReleaseEntry(struct NameTable *NTable_ptr)
884 {
885   --NoOfNTableEntries;
886 
887   free( NTable_ptr->Entry.symbol );
888   NTable_ptr->sym_type = UNUSED_SYM;
889   NTable_ptr->Entry.next = free_NTable_entry;
890   free_NTable_entry = NTable_ptr;
891 }
892 
893 
894 /*****************************************************************************
895   FUNCTION : krm_releaseNTableArrays
896 
897   PURPOSE  : release all name-table blocks
898   NOTES    :
899 
900   RETURNS  :
901   UPDATE   :
902 ******************************************************************************/
krm_releaseNTableArrays(void)903 static void  krm_releaseNTableArrays(void)
904 {
905   struct NameTable     *tmp_ptr;
906 
907 
908   NoOfNTableEntries      = 0;
909   NoOfAllocNTableEntries = 0;
910 
911   if (NTable_array != NULL)  {
912     for (tmp_ptr = NTable_array - 1; tmp_ptr > NTable_block_list; --tmp_ptr)  {
913       if (tmp_ptr->sym_type != UNUSED_SYM)
914         free( tmp_ptr->Entry.symbol );    /*  free symbols */
915     }
916 
917     tmp_ptr = NTable_block_list->Entry.next;
918     free( (char *) NTable_block_list );
919     NTable_block_list = tmp_ptr;
920 
921     while (NTable_block_list != NULL)  {
922       for (tmp_ptr = NTable_block_list + NTABLE_BLOCK;
923            tmp_ptr > NTable_block_list; --tmp_ptr)  {
924         if (tmp_ptr->sym_type != UNUSED_SYM)
925           free( tmp_ptr->Entry.symbol );   /*  free symbols */
926       }
927 
928       tmp_ptr =  NTable_block_list->Entry.next;
929       free( (char *) NTable_block_list );
930       NTable_block_list = tmp_ptr;
931     }
932 
933     free_NTable_entry = NULL;
934     NTable_array      = NULL;
935   }
936 }
937 
938 
939 /*****************************************************************************
940   FUNCTION : krm_NTableSymbolSearch
941 
942   PURPOSE  : Searches for a given symbol and symbol-type in the name table.
943   NOTES    :
944 
945   RETURNS  : Returns symbol ptr if symbol was found, NULL otherwise.
946   UPDATE   :
947 ******************************************************************************/
krm_NTableSymbolSearch(char * symbol,int sym_type)948 struct  NameTable   *krm_NTableSymbolSearch(char *symbol, int sym_type)
949 {
950   int   symbol_type;
951   struct  NameTable   *n_ptr,
952                       *block_list;
953 
954 
955   if (NTable_array == NULL)  return( NULL );
956 
957   block_list = NTable_block_list;
958   for (n_ptr = NTable_array - 1; n_ptr > block_list; n_ptr--)  {
959     symbol_type = (int) n_ptr->sym_type;
960     if ( (symbol_type != UNUSED_SYM) &&
961          (symbol_type == sym_type) &&
962          (strcmp( n_ptr->Entry.symbol, symbol ) == 0) )
963       return( n_ptr );    /*  symbol was found    */
964   }
965 
966   for (block_list = block_list->Entry.next;
967        block_list != NULL;
968        block_list = block_list->Entry.next)  {
969     for (n_ptr = block_list + NTABLE_BLOCK; n_ptr > block_list; n_ptr--)  {
970       symbol_type = (int) n_ptr->sym_type;
971       if ( (symbol_type != UNUSED_SYM) &&
972            (symbol_type == sym_type) &&
973            (strcmp( n_ptr->Entry.symbol, symbol ) == 0) )
974         return( n_ptr );    /*  symbol was found    */
975     }
976   }
977 
978   return( NULL );
979 }
980 
981 
982 /*****************************************************************************
983   FUNCTION : krm_NTableCreateEntry
984 
985   PURPOSE  : Creates a new symbol in the name-table
986   NOTES    :
987 
988   RETURNS  : Returns name-table ptr or NULL if memory alloc has failed.
989   UPDATE   :
990 ******************************************************************************/
krm_NTableCreateEntry(char * symbol_name,int symbol_type)991 struct NameTable  *krm_NTableCreateEntry(char *symbol_name, int symbol_type)
992 {
993   char   *str_ptr;
994   struct  NameTable     *n_ptr;
995 
996 
997   KernelErrorCode = KRERR_NO_ERROR;
998 
999   if ( (n_ptr = krm_getNTableEntry() ) == NULL)
1000     return( NULL );     /*  memory alloc failed */
1001 
1002   if ((str_ptr = (char *) strdup( symbol_name ) ) == NULL)
1003     {  /*  memory alloc failed */
1004     KernelErrorCode = KRERR_INSUFFICIENT_MEM;
1005     return( NULL );
1006   }
1007 
1008   n_ptr->Entry.symbol = str_ptr;
1009   n_ptr->sym_type = (unsigned short) symbol_type;
1010 
1011   return( n_ptr );
1012 }
1013 
1014 
1015 /*****************************************************************************
1016   FUNCTION : krm_NTableInsertSymbol
1017 
1018   PURPOSE  : Inserts a symbol in the name-table. This function duplicates
1019              symbol ptrs if the symbol was found in the name-table.
1020   NOTES    :
1021 
1022   RETURNS  : Returns symbol ptr or NULL if memory alloc has failed
1023   UPDATE   :
1024 ******************************************************************************/
krm_NTableInsertSymbol(char * symbol_name,int symbol_type)1025 char  *krm_NTableInsertSymbol(char *symbol_name, int symbol_type)
1026 {
1027   struct NameTable  *n_ptr;
1028 
1029 
1030   if ( (n_ptr = krm_NTableSymbolSearch( symbol_name, symbol_type ) ) != NULL)
1031     {   /*  symbol is already in the name table  */
1032     if ((n_ptr->ref_count) < ((unsigned short) SHRT_MAX)) {
1033         n_ptr->ref_count++;
1034     }
1035     return( n_ptr->Entry.symbol );
1036   }
1037 
1038   n_ptr = krm_NTableCreateEntry( symbol_name, symbol_type );
1039   return( n_ptr->Entry.symbol );
1040 }
1041 
1042 
1043 /*****************************************************************************
1044   FUNCTION : krm_NTableReleaseSymbol
1045 
1046   PURPOSE  : release name-table entry if there is no other reference to this
1047              symbol
1048   NOTES    :
1049 
1050   RETURNS  :
1051   UPDATE   :
1052 ******************************************************************************/
krm_NTableReleaseSymbol(char * symbol_name,int symbol_type)1053 void  krm_NTableReleaseSymbol(char *symbol_name, int symbol_type)
1054 {
1055   struct NameTable  *n_ptr;
1056 
1057 
1058   if (symbol_name == NULL)  return;
1059   if ( (n_ptr = krm_NTableSymbolSearch( symbol_name, symbol_type ) ) != NULL)
1060     {   /*  symbol is in the name table  */
1061     if ((n_ptr->ref_count) < ((unsigned short) SHRT_MAX))
1062       {   /*    No. of references to this symbol don't exceed the max. reference
1063                 count. This means it is possible to delete the symbol if the
1064                 reference count is zero.
1065           */
1066       if (--(n_ptr->ref_count) == 0)
1067         krm_NTableReleaseEntry( n_ptr );
1068     }
1069   }
1070 }
1071 
1072 
1073 /*****************************************************************************
1074   FUNCTION : krm_getNTableFirstEntry
1075 
1076   PURPOSE  : get the first name-table entry
1077   NOTES    :
1078 
1079   RETURNS  : the nametable
1080   UPDATE   :
1081 ******************************************************************************/
krm_getNTableFirstEntry(void)1082 struct NameTable       *krm_getNTableFirstEntry(void)
1083 {
1084   if (NTable_array == NULL)  return( NULL );
1085 
1086   curr_NTable_block = NTable_block_list;
1087   curr_NTable_entry = NTable_array - 1;
1088   return( curr_NTable_entry );
1089 }
1090 
1091 
1092 /*****************************************************************************
1093   FUNCTION : krm_getNTableNextEntry
1094 
1095   PURPOSE  : get the next name-table entry
1096   NOTES    :
1097 
1098   RETURNS  : the nametable
1099   UPDATE   :
1100 ******************************************************************************/
krm_getNTableNextEntry(void)1101 struct NameTable       *krm_getNTableNextEntry(void)
1102 {
1103   if ((NTable_array == NULL) || (curr_NTable_block == NULL))
1104     return( NULL );
1105 
1106   if (--curr_NTable_entry == curr_NTable_block)  {
1107     if ( (curr_NTable_block = curr_NTable_block->Entry.next) == NULL)
1108       return( NULL );
1109 
1110     curr_NTable_entry = curr_NTable_block + NTABLE_BLOCK;
1111   }
1112 
1113   return( curr_NTable_entry );
1114 }
1115 
1116 
1117 
1118 
1119 
1120 /*#################################################
1121 
1122 GROUP: SiteTable Functions
1123 
1124 #################################################*/
1125 /*****************************************************************************
1126   FUNCTION : krm_allocSTableArray
1127 
1128   PURPOSE  : allocate another site-table block
1129   NOTES    :
1130 
1131   RETURNS  :
1132   UPDATE   :
1133 ******************************************************************************/
krm_allocSTableArray(void)1134 static int  krm_allocSTableArray(void)
1135 {
1136   STableArray     tmp_ptr;
1137 
1138 
1139   tmp_ptr = (STableArray) calloc( STABLE_BLOCK + 1, STABLE_SIZE );
1140   if (tmp_ptr == NULL)  return( 1 );
1141 
1142   if (STable_array == NULL)  {
1143     tmp_ptr->Entry.next = NULL;     /*  free site-table block sentinel  */
1144     free_STable_entry = tmp_ptr;    /*  free site-table entry sentinel  */
1145   }
1146   else  {
1147     tmp_ptr->Entry.next = STable_block_list;    /*  append new site-table block
1148                                                     to block list   */
1149   }
1150 
1151   STable_block_list = tmp_ptr;      /*  update block list ptr  */
1152   NoOfAllocSTableEntries += STABLE_BLOCK;
1153   STable_array = tmp_ptr + 1;       /* STable_array points to the first entry */
1154   return( 0 );
1155 }
1156 
1157 
1158 /*****************************************************************************
1159   FUNCTION : krm_allocSTableArray
1160 
1161   PURPOSE  : get one site-table entry
1162   NOTES    :
1163 
1164   RETURNS  :
1165   UPDATE   :
1166 ******************************************************************************/
krm_getSTableEntry(void)1167 static  struct SiteTable    *krm_getSTableEntry(void)
1168 {
1169   struct SiteTable  *tmp_ptr;
1170 
1171 
1172   KernelErrorCode = KRERR_NO_ERROR;
1173   if ((STable_array == NULL) || (NoOfSTableEntries == NoOfAllocSTableEntries))
1174     if (krm_allocSTableArray() != 0)  {
1175       KernelErrorCode = KRERR_INSUFFICIENT_MEM;
1176       return( NULL );
1177     }
1178 
1179   NoOfSTableEntries++;
1180 
1181   if (free_STable_entry->Entry.next != NULL)
1182     {   /*  a previous released site-table entry is availabe    */
1183     tmp_ptr = free_STable_entry;
1184     free_STable_entry = free_STable_entry->Entry.next;
1185   }
1186   else  {
1187     tmp_ptr = STable_array++;
1188   }
1189 
1190   return( tmp_ptr );
1191 }
1192 
1193 
1194 /*****************************************************************************
1195   FUNCTION : krm_releaseSTableEntry
1196 
1197   PURPOSE  : release site table block
1198   NOTES    :
1199 
1200   RETURNS  :
1201   UPDATE   :
1202 ******************************************************************************/
krm_releaseSTableEntry(struct SiteTable * STable_ptr)1203 static  void    krm_releaseSTableEntry(struct SiteTable *STable_ptr)
1204 {
1205   --NoOfSTableEntries;
1206 
1207   STable_ptr->site_func  = NULL;
1208   STable_ptr->Entry.next = free_STable_entry;
1209   free_STable_entry = STable_ptr;
1210 }
1211 
1212 
1213 /*****************************************************************************
1214   FUNCTION : krm_releaseSTableArrays
1215 
1216   PURPOSE  : release all site-table blocks
1217   NOTES    :
1218 
1219   RETURNS  :
1220   UPDATE   :
1221 ******************************************************************************/
krm_releaseSTableArrays(void)1222 static  void    krm_releaseSTableArrays(void)
1223 {
1224   struct SiteTable     *tmp_ptr;
1225 
1226 
1227   NoOfSTableEntries      = 0;
1228   NoOfAllocSTableEntries = 0;
1229 
1230   if (STable_array != NULL)  {
1231     while (STable_block_list != NULL)  {
1232       tmp_ptr =  STable_block_list->Entry.next;
1233       free( (char *) STable_block_list );
1234       STable_block_list = tmp_ptr;
1235     }
1236 
1237     free_STable_entry = NULL;
1238     STable_array      = NULL;
1239   }
1240 }
1241 
1242 
1243 /*****************************************************************************
1244   FUNCTION : krm_STableCreateEntry
1245 
1246   PURPOSE  : create new site-table entry
1247   NOTES    :
1248 
1249   RETURNS  :
1250   UPDATE   :
1251 ******************************************************************************/
krm_STableCreateEntry(char * site_symbol,SiteFuncPtr site_func)1252 struct SiteTable *krm_STableCreateEntry(char *site_symbol,
1253 					SiteFuncPtr site_func)
1254 {
1255   struct  NameTable     *n_ptr;
1256   struct  SiteTable     *s_ptr;
1257 
1258 
1259   if ( (s_ptr = krm_getSTableEntry() ) == NULL)
1260     return( NULL );     /*  memory alloc failed */
1261 
1262   if ((n_ptr = krm_NTableCreateEntry( site_symbol, SITE_SYM ) ) == NULL)  {
1263     krm_releaseSTableEntry( s_ptr );
1264     return( NULL );     /*  memory alloc failed */
1265   }
1266 
1267   s_ptr->Entry.site_name = n_ptr;
1268   s_ptr->site_func       = site_func;
1269 
1270   return( s_ptr );
1271 }
1272 
1273 
1274 /*****************************************************************************
1275   FUNCTION : krm_STableChangeEntry
1276 
1277   PURPOSE  : change the properties of the given site-table entry
1278   NOTES    :
1279 
1280   RETURNS  :
1281   UPDATE   :
1282 ******************************************************************************/
krm_STableChangeEntry(struct SiteTable * stbl_ptr,char * new_site_name,SiteFuncPtr new_site_func)1283 struct  SiteTable   *krm_STableChangeEntry(struct SiteTable *stbl_ptr,
1284 					   char *new_site_name,
1285 					   SiteFuncPtr new_site_func)
1286 {
1287   struct  NameTable     *n_ptr;
1288 
1289 
1290   if ((n_ptr = krm_NTableCreateEntry( new_site_name, SITE_SYM ) ) == NULL)
1291     return( NULL );     /*  memory alloc failed */
1292 
1293   krm_NTableReleaseEntry( stbl_ptr->Entry.site_name );
1294 
1295   stbl_ptr->Entry.site_name = n_ptr;
1296   stbl_ptr->site_func       = new_site_func;
1297 
1298   return( stbl_ptr );
1299 }
1300 
1301 
1302 /*****************************************************************************
1303   FUNCTION : krm_STableRemoveEntry
1304 
1305   PURPOSE  : release a previosly defined site-table entry
1306   NOTES    :
1307 
1308   RETURNS  :
1309   UPDATE   :
1310 ******************************************************************************/
krm_STableRemoveEntry(struct SiteTable * STable_ptr)1311 void    krm_STableRemoveEntry(struct SiteTable *STable_ptr)
1312 {
1313   krm_NTableReleaseEntry( STable_ptr->Entry.site_name );
1314   krm_releaseSTableEntry( STable_ptr );
1315 }
1316 
1317 
1318 /*****************************************************************************
1319   FUNCTION : krm_STableSymbolSearch
1320 
1321   PURPOSE  : searches for a symbol in the site-table
1322   NOTES    :
1323 
1324   RETURNS  :
1325   UPDATE   :
1326 ******************************************************************************/
krm_STableSymbolSearch(char * site_symbol)1327 struct SiteTable    *krm_STableSymbolSearch(char *site_symbol)
1328 {
1329   struct  NameTable   *n_ptr;
1330   struct  SiteTable   *s_ptr,
1331                       *block_list;
1332 
1333 
1334   if (STable_array == NULL)
1335     return( NULL );     /*  there are no site-table entries */
1336 
1337   if ( (n_ptr = krm_NTableSymbolSearch( site_symbol , SITE_SYM ) ) == NULL)
1338     return( NULL );     /*  symbol dosn't exist */
1339 
1340 
1341   block_list = STable_block_list;
1342   for (s_ptr = STable_array - 1; s_ptr > block_list; s_ptr--)
1343     if ( (s_ptr->site_func != NULL) &&
1344          (s_ptr->Entry.site_name == n_ptr ) )
1345       return( s_ptr );
1346 
1347   for (block_list = block_list->Entry.next;
1348        block_list != NULL;
1349        block_list = block_list->Entry.next)  {
1350     for (s_ptr = block_list + STABLE_BLOCK; s_ptr > block_list; s_ptr--)
1351       if ( (s_ptr->site_func != NULL) &&
1352            (s_ptr->Entry.site_name == n_ptr ) )
1353         return( s_ptr );
1354   }
1355 
1356   return( NULL );  /*  the site symbol is in the name table, but not in
1357 		       the site table: Error */
1358 }
1359 
1360 
1361 /*****************************************************************************
1362   FUNCTION : krm_getSTableNextRawEntry
1363 
1364   PURPOSE  :
1365   NOTES    :
1366 
1367   RETURNS  : returns a pointer to the next (used or unused) site-table entry
1368   UPDATE   :
1369 ******************************************************************************/
krm_getSTableNextRawEntry(void)1370 static struct SiteTable       *krm_getSTableNextRawEntry(void)
1371 {
1372   if ((STable_array == NULL) || (curr_STable_block == NULL))
1373     return( NULL );
1374 
1375   if (--curr_STable_entry == curr_STable_block)
1376     {  /*  get new site-table block  */
1377     if ( (curr_STable_block = curr_STable_block->Entry.next) == NULL)  {
1378       curr_STable_block = NULL;
1379       curr_STable_entry = NULL;
1380 
1381       return( NULL );
1382     }
1383 
1384     /* next site-table block  */
1385     curr_STable_entry = curr_STable_block + STABLE_BLOCK;
1386   }
1387 
1388   return( curr_STable_entry );
1389 }
1390 
1391 
1392 /*****************************************************************************
1393   FUNCTION : krm_getSTableNextEntry
1394 
1395   PURPOSE  :
1396   NOTES    :
1397 
1398   RETURNS  : returns a pointer to the next used site-table entry
1399   UPDATE   :
1400 ******************************************************************************/
krm_getSTableNextEntry(void)1401 struct SiteTable       *krm_getSTableNextEntry(void)
1402 {
1403   struct  SiteTable   *stbl_ptr;
1404 
1405 
1406   if ((stbl_ptr = krm_getSTableNextRawEntry()) == NULL)
1407     return( NULL );
1408 
1409   while ( stbl_ptr->site_func == NULL)	/*  return only used site-table entries  */
1410     if ((stbl_ptr = krm_getSTableNextRawEntry()) == NULL)
1411       return( NULL );
1412 
1413   return( stbl_ptr );
1414 }
1415 
1416 
1417 /*****************************************************************************
1418   FUNCTION : krm_getSTableFirstEntry
1419 
1420   PURPOSE  :
1421   NOTES    :
1422 
1423   RETURNS  : returns a pointer to the first used site-table entry
1424   UPDATE   :
1425 ******************************************************************************/
krm_getSTableFirstEntry(void)1426 struct SiteTable       *krm_getSTableFirstEntry(void)
1427 {
1428   struct  SiteTable   *stbl_ptr;
1429 
1430 
1431   if (STable_array == NULL)  return( NULL );
1432 
1433   curr_STable_block = STable_block_list;
1434   curr_STable_entry = STable_array - 1;
1435   stbl_ptr = curr_STable_entry;
1436 
1437   if (stbl_ptr->site_func == NULL)  /*	return only used site-table entries  */
1438     if ((stbl_ptr = krm_getSTableNextEntry()) == NULL)
1439       return( NULL );
1440 
1441   return( stbl_ptr );
1442 }
1443 
1444 
1445 
1446 
1447 
1448 /*#################################################
1449 
1450 GROUP: Ftype entry functions
1451 
1452 #################################################*/
1453 
1454 /*****************************************************************************
1455   FUNCTION : krm_getFtypeEntry
1456 
1457   PURPOSE  : allocate a new Ftype entry
1458   NOTES    :
1459 
1460   RETURNS  :
1461   UPDATE   :
1462 ******************************************************************************/
krm_getFtypeEntry(void)1463 struct FtypeUnitStruct  *krm_getFtypeEntry(void)
1464 {
1465   struct FtypeUnitStruct  *Ftype_entry;
1466 
1467 
1468   KernelErrorCode = KRERR_NO_ERROR;
1469   if ((Ftype_entry =
1470            (struct FtypeUnitStruct *) malloc( FTYPE_UNIT_SIZE ) ) == NULL)
1471     {  /*  memory alloc failed */
1472     KernelErrorCode = KRERR_INSUFFICIENT_MEM;
1473     return( NULL );
1474   }
1475 
1476   if (Ftype_list_root != NULL)  {
1477     Ftype_list_root->prev = Ftype_entry;
1478     Ftype_entry->next = Ftype_list_root;
1479   }
1480   else
1481     Ftype_entry->next = NULL;
1482 
1483   Ftype_list_root   = Ftype_entry;
1484   Ftype_entry->prev = NULL;
1485 
1486   Ftype_entry->sites = NULL;
1487   Ftype_entry->Ftype_symbol = NULL;
1488 
1489   ++NoOfFTableEntries;
1490 
1491   return( Ftype_entry );
1492 }
1493 
1494 
1495 /*****************************************************************************
1496   FUNCTION : krm_releaseFtypeEntry
1497 
1498   PURPOSE  : free a previosly defined Ftype entry
1499   NOTES    :
1500 
1501   RETURNS  :
1502   UPDATE   :
1503 ******************************************************************************/
krm_releaseFtypeEntry(struct FtypeUnitStruct * Ftype_entry)1504 void    krm_releaseFtypeEntry(struct FtypeUnitStruct *Ftype_entry)
1505 {
1506   struct  FtypeUnitStruct   *next_entry,
1507                             *prev_entry;
1508 
1509 
1510   /*  release sites first */
1511   if ( Ftype_entry->sites != NULL)
1512     krm_releaseAllSites( Ftype_entry->sites );
1513 
1514   /*  release Ftype symbol name */
1515   if ( Ftype_entry->Ftype_symbol != NULL )
1516     krm_NTableReleaseEntry( Ftype_entry->Ftype_symbol );
1517 
1518   next_entry = Ftype_entry->next;
1519   prev_entry = Ftype_entry->prev;
1520 
1521   if (prev_entry != NULL)
1522     prev_entry->next = next_entry;
1523   else
1524     Ftype_list_root = next_entry;
1525 
1526   if (next_entry != NULL)
1527     next_entry->prev = prev_entry;
1528 
1529   /*  release unit entry  */
1530   free( (char *) Ftype_entry );       /*  release Ftype entry   */
1531 
1532   --NoOfFTableEntries;
1533 }
1534 
1535 /*****************************************************************************
1536   FUNCTION : krm_FtypeCreateEntry
1537 
1538   PURPOSE  : create and define a Ftype entry
1539   NOTES    :
1540 
1541   RETURNS  : the ftype
1542   UPDATE   :
1543 ******************************************************************************/
krm_FtypeCreateEntry(char * Ftype_symbol,OutFuncPtr out_func,ActFuncPtr act_func,ActDerivFuncPtr act_deriv_func,ActDerivFuncPtr act_2_deriv_func,PyObject * python_out_func,PyObject * python_act_func,PyObject * python_act_deriv_func,PyObject * python_act_2_deriv_func)1544 struct FtypeUnitStruct  *krm_FtypeCreateEntry(char *Ftype_symbol, OutFuncPtr out_func, ActFuncPtr act_func, ActDerivFuncPtr act_deriv_func, ActDerivFuncPtr act_2_deriv_func, PyObject *python_out_func,PyObject *python_act_func,PyObject *python_act_deriv_func,   PyObject *python_act_2_deriv_func)
1545 {
1546   struct  FtypeUnitStruct   *Ftype_entry;
1547   struct  NameTable         *n_ptr;
1548 
1549 
1550   if ( (Ftype_entry = krm_getFtypeEntry() ) == NULL)
1551     return( NULL );     /*  memory alloc failed */
1552 
1553   if((n_ptr = krm_NTableCreateEntry( Ftype_symbol, FTYPE_UNIT_SYM ) ) == NULL) {
1554     krm_releaseFtypeEntry( Ftype_entry );
1555     return( NULL );     /*  memory alloc failed */
1556   }
1557 
1558   Ftype_entry->Ftype_symbol = n_ptr;
1559   Ftype_entry->out_func = out_func;
1560   Ftype_entry->act_func = act_func;
1561   Ftype_entry->act_deriv_func = act_deriv_func;
1562   Ftype_entry->act_2_deriv_func = act_2_deriv_func;
1563   Ftype_entry->python_out_func = python_out_func;
1564   Ftype_entry->python_act_func = python_act_func;
1565   Ftype_entry->python_act_deriv_func = python_act_deriv_func;
1566   Ftype_entry->python_act_2_deriv_func = python_act_2_deriv_func;
1567   Ftype_entry->sites = NULL;
1568 
1569   return( Ftype_entry );
1570 }
1571 
1572 
1573 /*****************************************************************************
1574   FUNCTION : krm_FtypeAddSite
1575 
1576   PURPOSE  : add a site to a previosly defined Ftype entry
1577   NOTES    :
1578 
1579   RETURNS  : the site
1580   UPDATE   :
1581 ******************************************************************************/
krm_FtypeAddSite(struct FtypeUnitStruct * Ftype_entry,struct SiteTable * STable_entry)1582 struct Site  *krm_FtypeAddSite(struct FtypeUnitStruct *Ftype_entry,
1583 			       struct SiteTable *STable_entry)
1584 {
1585   struct  Site   *site_ptr;
1586 
1587 
1588   if ( (site_ptr = krm_getFtypeSite() ) == NULL)
1589     return( NULL );     /*  memory alloc failed */
1590 
1591   site_ptr->next = Ftype_entry->sites;
1592   Ftype_entry->sites = site_ptr;
1593 
1594   site_ptr->site_table = STable_entry;
1595 
1596   return( site_ptr );
1597 }
1598 
1599 
1600 /*****************************************************************************
1601   FUNCTION : krm_getFtypeFirstEntry
1602 
1603   PURPOSE  :
1604   NOTES    :
1605 
1606   RETURNS  : returns a pointer to first Ftype entry
1607   UPDATE   :
1608 ******************************************************************************/
krm_getFtypeFirstEntry(void)1609 struct FtypeUnitStruct  *krm_getFtypeFirstEntry(void)
1610 {
1611   curr_Ftype_entry = Ftype_list_root;
1612   return( Ftype_list_root );
1613 }
1614 
1615 
1616 /*****************************************************************************
1617   FUNCTION : krm_getFtypeNextEntry
1618 
1619   PURPOSE  :
1620   NOTES    :
1621 
1622   RETURNS  : returns a pointer to next Ftype entry
1623   UPDATE   :
1624 ******************************************************************************/
krm_getFtypeNextEntry(void)1625 struct FtypeUnitStruct  *krm_getFtypeNextEntry(void)
1626 {
1627   if (curr_Ftype_entry != NULL)  {
1628     if (curr_Ftype_entry->next != NULL)
1629       curr_Ftype_entry = curr_Ftype_entry->next;
1630     else
1631       return( NULL );
1632   }
1633 
1634   return( curr_Ftype_entry );
1635 }
1636 
1637 
1638 /*****************************************************************************
1639   FUNCTION : krm_getFtypeNextEntry
1640 
1641   PURPOSE  : searches for a Ftype entry with the given name
1642   NOTES    :
1643 
1644   RETURNS  :
1645   UPDATE   :
1646 ******************************************************************************/
krm_FtypeSymbolSearch(char * Ftype_symbol)1647 struct  FtypeUnitStruct  *krm_FtypeSymbolSearch(char *Ftype_symbol)
1648 {
1649   struct  FtypeUnitStruct   *ftype_entry;
1650 
1651 
1652   if (Ftype_symbol == NULL)  return( NULL);
1653 
1654   ftype_entry = Ftype_list_root;
1655   while (ftype_entry != NULL)  {
1656     if (strcmp( Ftype_symbol, (ftype_entry->Ftype_symbol)->Entry.symbol ) == 0)
1657       return( ftype_entry );
1658 
1659     ftype_entry = ftype_entry->next;
1660   }
1661 
1662   return( NULL );
1663 }
1664 
1665 
1666 /*****************************************************************************
1667   FUNCTION : krm_releaseFtypeList
1668 
1669   PURPOSE  : releases all Ftype entries
1670   NOTES    :
1671 
1672   RETURNS  :
1673   UPDATE   :
1674 ******************************************************************************/
krm_releaseFtypeList(void)1675 void    krm_releaseFtypeList(void)
1676 {
1677   struct  FtypeUnitStruct   *Ftype_entry,
1678                             *ft_ptr;
1679 
1680 
1681   Ftype_entry = Ftype_list_root;
1682 
1683   while( Ftype_entry != NULL )  {
1684     /*  release sites first */
1685     if ( Ftype_entry->sites != NULL)
1686       krm_releaseAllFtypeSites( Ftype_entry->sites );
1687 
1688     /*  release Ftype symbol name */
1689     if ( Ftype_entry->Ftype_symbol != NULL )
1690       krm_NTableReleaseEntry( Ftype_entry->Ftype_symbol );
1691 
1692     ft_ptr = Ftype_entry;
1693     Ftype_entry = Ftype_entry->next;
1694     /*  release unit entry  */
1695     free( (char *) ft_ptr );       /*  release Ftype entry   */
1696   }
1697 
1698   Ftype_list_root = NULL;
1699   NoOfFTableEntries = 0;
1700 }
1701 
1702 
1703 
1704 #ifdef MASPAR_KERNEL
1705 #ifdef MASPAR_KERNEL_EMULATION
1706 
1707 /*#################################################
1708 
1709 GROUP: Functions for the MasPar kernel
1710 
1711 #################################################*/
1712 /*****************************************************************************
1713   FUNCTION : krm_releaseWeightArrays
1714 
1715   PURPOSE  : release weight arrays from memory
1716   NOTES    :
1717 
1718   RETURNS  :
1719   UPDATE   :
1720 ******************************************************************************/
krm_releaseWeightArrays(void)1721 void  krm_releaseWeightArrays(void)
1722 {
1723   int  dest_layer, src_layer;
1724   FlintType  *weight_array;
1725 
1726   /*  get weight array pointers  */
1727   for (dest_layer = 1; dest_layer < descrFFnet.no_of_layers; dest_layer++)
1728     for (src_layer = 0; src_layer < dest_layer; src_layer++)  {
1729       weight_array =
1730 	  descrFFnet.layers[dest_layer].inputs[src_layer].weight_array;
1731       if (weight_array != NULL)  {
1732         free( (char *) weight_array );
1733 	descrFFnet.layers[ dest_layer ].inputs[src_layer].weight_array = NULL;
1734 	descrFFnet.layers[ dest_layer ].inputs[src_layer].no_of_inputs = 0;
1735       }
1736     }
1737 
1738   NoOfWeights = 0;
1739   specialNetworkType == NET_TYPE_GENERAL;
1740 }
1741 
1742 
1743 /*****************************************************************************
1744   FUNCTION :  krm_createWeightArrays
1745 
1746   PURPOSE  :  creates arrays containing connection weights for feedforward
1747               networks
1748   NOTES    :
1749 
1750   RETURNS  :
1751   UPDATE   :
1752 ******************************************************************************/
krm_createWeightArrays(void)1753 krui_err  krm_createWeightArrays(void)
1754 {
1755   int  dest_layer, src_layer, no_of_inputs;
1756   FlintType  *weight_array;
1757 
1758   KernelErrorCode = KRERR_NO_ERROR;
1759   NoOfWeights = 0;
1760 
1761   /*  allocate weight arrays  */
1762   for (dest_layer = 1; dest_layer < descrFFnet.no_of_layers; dest_layer++)
1763     for (src_layer = 0; src_layer < dest_layer; src_layer++)  {
1764 	no_of_inputs =
1765 	    descrFFnet.layers[ dest_layer ].inputs[src_layer].no_of_inputs;
1766       if (no_of_inputs > 0)
1767         {  /*  there are <no_of_inputs> connections between layer <src_layer>
1768                and layer <dest_layer>.  */
1769 	weight_array = (FlintType *) calloc( no_of_inputs, sizeof (FlintType) );
1770         if (weight_array == NULL)
1771           {  /*  insufficient memory  */
1772           KernelErrorCode = KRERR_INSUFFICIENT_MEM;
1773           krm_releaseWeightArrays();
1774           return( KernelErrorCode );
1775         }
1776 
1777 	descrFFnet.layers[dest_layer].inputs[src_layer].weight_array =
1778 	    weight_array;
1779       }
1780     }
1781 
1782   NoOfWeights = descrFFnet.no_of_weights;
1783   return( KernelErrorCode );
1784 }
1785 
1786 #endif
1787 #endif
1788 
1789 
1790 
1791 /*#################################################
1792 
1793 GROUP: Memory cleanup
1794 
1795 #################################################*/
1796 /*****************************************************************************
1797   FUNCTION :  krm_releaseMem
1798 
1799   PURPOSE  :  frees all memory used for the internal representation of the
1800               network
1801   NOTES    :
1802 
1803   RETURNS  :
1804   UPDATE   :
1805 ******************************************************************************/
krm_releaseMem(void)1806 void    krm_releaseMem(void)
1807 {
1808 #ifdef MASPAR_KERNEL
1809 #ifdef MASPAR_KERNEL_EMULATION
1810 
1811   if (specialNetworkType == NET_TYPE_FF1)
1812     krm_releaseWeightArrays();
1813 
1814 #endif
1815 #endif
1816 
1817   specialNetworkType = NET_TYPE_GENERAL;
1818   krm_releaseFtypeList();
1819   krm_releaseSTableArrays();
1820   krm_releaseNTableArrays();
1821   krm_releaseLinkArrays();
1822   krm_releaseSiteArrays();
1823   krm_releaseUnitArrays();
1824   krm_releaseUnitTopoArray();
1825 
1826 
1827   if (transTable != NULL)  {
1828     free( (void *) transTable );
1829     transTable = NULL;
1830     transTableSize = 0;
1831   }
1832 
1833 
1834 }
1835 
1836 
1837 /*  ---------------------  End of Memory Management Functions  -------------  */
1838 
1839 /*  ---------------------    Begin Enzo Interface Functions   -------------  */
1840 #ifdef __ENZO__
1841 /*****************************************************************************
1842   FUNCTION : krm_getNet
1843 
1844   PURPOSE  : Receiving a network from the Enzo network manager modul
1845   RETURNS  :
1846   NOTES    :
1847 
1848   UPDATE   :
1849 ******************************************************************************/
krm_getNet(memNet * n)1850 void krm_getNet( memNet *n )
1851 {                              /* the patterns stay untouched! */
1852     char *afunc, *ofunc;
1853 
1854     strcpy(n->update_func, krui_getUpdateFunc());
1855     strcpy(n->learn_func,  krui_getLearnFunc());
1856     strcpy(n->init_func,   krui_getInitialisationFunc());
1857 
1858     kr_getUnitDefaults( &n->u_act, &n->u_bias, &n->u_ttflags,
1859 		        &n->u_subnet_no, &n->u_layer_no,
1860 			&afunc, &ofunc                         );
1861 
1862     strcpy( n->u_act_func, afunc );
1863     strcpy( n->u_out_func, ofunc );
1864 
1865     n->NoOfLinks   = NoOfLinks;
1866     n->NoOfAllocLinks  = NoOfAllocLinks;
1867     n->link_array  = link_array;
1868     n->link_block_list   = link_block_list;
1869     n->free_link_ptr   = free_link_ptr;
1870 
1871     n->NoOfSites   = NoOfSites;
1872     n->NoOfNetSites  = NoOfNetSites;
1873     n->NoOfAllocSites  = NoOfAllocSites;
1874     n->site_array  = site_array;
1875     n->site_block_list   = site_block_list;
1876     n->free_site_ptr   = free_site_ptr;
1877     n->site_array  = site_array;
1878 
1879 
1880     n->NoOfAllocUnits  = NoOfAllocUnits;
1881     n->FreeUnitIndex   = FreeUnitIndex;
1882     n->NoOfUnits   = NoOfUnits;
1883     n->NoOfInputUnits  = NoOfInputUnits;
1884     n->NoOfOutputUnits   = NoOfOutputUnits;
1885     n->NoOfHiddenUnits   = NoOfHiddenUnits;
1886     n->MaxUnitNo   = MaxUnitNo;
1887     n->MinUnitNo   = MinUnitNo;
1888     n->unit_array  = unit_array;
1889 
1890     n->topo_ptr_array  = topo_ptr_array;
1891 
1892     n->NoOfNTableEntries   = NoOfNTableEntries;
1893     n->NoOfAllocNTableEntries  = NoOfAllocNTableEntries;
1894     n->NTable_array  = NTable_array;
1895     n->NTable_block_list   = NTable_block_list;
1896     n->free_NTable_entry   = free_NTable_entry;
1897     n->NTable_array  = NTable_array;
1898 
1899     n->NoOfSTableEntries   = NoOfSTableEntries;
1900     n->NoOfAllocSTableEntries  = NoOfAllocSTableEntries;
1901     n->STable_array  = STable_array;
1902     n->STable_block_list   = STable_block_list;
1903     n->free_STable_entry   = free_STable_entry;
1904     n->STable_array  = STable_array;
1905 
1906     n->Ftype_list_root   = Ftype_list_root;
1907     n->NoOfFTableEntries   = NoOfFTableEntries;
1908 
1909 
1910 
1911     n->curr_Ftype_entry = curr_Ftype_entry;
1912     n->curr_STable_entry = curr_STable_entry;
1913     n->curr_STable_block = curr_STable_block;
1914     n->curr_NTable_entry = curr_NTable_entry;
1915     n->curr_NTable_block = curr_NTable_block;
1916     n->NetModified =  NetModified;
1917     n->NetInitialize = NetInitialize;
1918     n->LearnFuncHasChanged = LearnFuncHasChanged;
1919     n->unitPtr =  unitPtr;
1920     n->sitePtr = sitePtr;
1921     n->prevSitePtr = prevSitePtr;
1922     n->linkPtr = linkPtr;
1923     n->prevLinkPtr = prevLinkPtr;
1924     n->unitNo = unitNo;
1925     n->specialNetworkType = specialNetworkType;
1926     n->TopoSortID = TopoSortID;
1927     n->no_of_topo_units = no_of_topo_units;
1928 
1929     /* treat this just as the net would have been deleted */
1930 
1931     NoOfLinks   = 0;
1932     NoOfAllocLinks  = 0;
1933     link_array  = NULL;
1934     link_block_list   = NULL;
1935     free_link_ptr   = NULL;
1936 
1937     NoOfSites   = 0;
1938     NoOfNetSites  = 0;
1939     NoOfAllocSites  = 0;
1940     site_array  = NULL;
1941     site_block_list   = NULL;
1942     free_site_ptr   = NULL;
1943 
1944     NoOfAllocUnits  = 0;
1945     FreeUnitIndex   = 0;
1946     NoOfUnits   = 0;
1947     NoOfInputUnits  = 0;
1948     NoOfOutputUnits   = 0;
1949     NoOfHiddenUnits   = 0;
1950     MaxUnitNo   = 0;
1951     unit_array  = NULL;
1952 
1953     topo_ptr_array  = NULL;
1954 
1955     NoOfNTableEntries   = 0;
1956     NoOfAllocNTableEntries  = 0;
1957     NTable_array  = NULL;
1958     NTable_block_list   = NULL;
1959     free_NTable_entry   = NULL;
1960     NTable_array  = NULL;
1961 
1962     NoOfSTableEntries   = 0;
1963     NoOfAllocSTableEntries  = 0;
1964     STable_array  = NULL;
1965     STable_block_list   = NULL;
1966     free_STable_entry   = NULL;
1967 
1968     Ftype_list_root   = NULL;
1969     NoOfFTableEntries   = 0;
1970 }
1971 
1972 
1973 
1974 /*****************************************************************************
1975   FUNCTION : krm_putNet
1976 
1977   PURPOSE  : Putting a network back under the control of the Enzo network
1978              manager modul
1979   RETURNS  :
1980   NOTES    :
1981 
1982   UPDATE   :
1983 ******************************************************************************/
krm_putNet(memNet * n)1984 void krm_putNet( memNet *n )
1985 {
1986 
1987     krm_releaseFtypeList();
1988     krm_releaseSTableArrays();
1989     krm_releaseNTableArrays();
1990     krm_releaseLinkArrays();
1991     krm_releaseSiteArrays();
1992     krm_releaseUnitArrays();
1993 
1994 
1995     krui_setUpdateFunc( n->update_func );
1996     krui_setLearnFunc( n->learn_func );
1997     krui_setInitialisationFunc( n->init_func );
1998 
1999     kr_setUnitDefaults( n->u_act, n->u_bias, n->u_ttflags,
2000 		        n->u_subnet_no, n->u_layer_no,
2001 		        n->u_act_func, n->u_out_func       );
2002 
2003     NoOfLinks   = n->NoOfLinks;
2004     NoOfAllocLinks  = n->NoOfAllocLinks;
2005     link_array  = n->link_array;
2006     link_block_list   = n->link_block_list;
2007     free_link_ptr   = n->free_link_ptr;
2008 
2009     NoOfSites   = n->NoOfSites;
2010     NoOfNetSites  = n->NoOfNetSites;
2011     NoOfAllocSites  = n->NoOfAllocSites;
2012     site_array  = n->site_array;
2013     site_block_list   = n->site_block_list;
2014     free_site_ptr   = n->free_site_ptr;
2015     site_array  = n->site_array;
2016 
2017     NoOfAllocUnits  = n->NoOfAllocUnits;
2018     FreeUnitIndex   = n->FreeUnitIndex;
2019     NoOfUnits   = n->NoOfUnits;
2020     NoOfInputUnits  = n->NoOfInputUnits;
2021     NoOfOutputUnits   = n->NoOfOutputUnits;
2022     NoOfHiddenUnits   = n->NoOfHiddenUnits;
2023     MinUnitNo   = n->MinUnitNo;
2024     MaxUnitNo   = n->MaxUnitNo;
2025     unit_array  = n->unit_array;
2026 
2027     topo_ptr_array  = n->topo_ptr_array;
2028 
2029     NoOfNTableEntries   = n->NoOfNTableEntries;
2030     NoOfAllocNTableEntries  = n->NoOfAllocNTableEntries;
2031     NTable_array  = n->NTable_array;
2032     NTable_block_list   = n->NTable_block_list;
2033     free_NTable_entry   = n->free_NTable_entry;
2034     NTable_array  = n->NTable_array;
2035 
2036     NoOfSTableEntries   = n->NoOfSTableEntries;
2037     NoOfAllocSTableEntries  = n->NoOfAllocSTableEntries;
2038     STable_array  = n->STable_array;
2039     STable_block_list   = n->STable_block_list;
2040     free_STable_entry   = n->free_STable_entry;
2041     STable_array  = n->STable_array;
2042 
2043     Ftype_list_root   = n->Ftype_list_root;
2044     NoOfFTableEntries   = n->NoOfFTableEntries;
2045 
2046     curr_Ftype_entry = n->curr_Ftype_entry;
2047     curr_STable_entry = n->curr_STable_entry;
2048     curr_STable_block = n->curr_STable_block;
2049     curr_NTable_entry = n->curr_NTable_entry;
2050     curr_NTable_block = n->curr_NTable_block;
2051     NetModified =  n->NetModified;
2052     NetInitialize = n->NetInitialize;
2053     LearnFuncHasChanged = n->LearnFuncHasChanged;
2054     unitPtr =  n->unitPtr;
2055     sitePtr = n->sitePtr;
2056     prevSitePtr = n->prevSitePtr;
2057     linkPtr = n->linkPtr;
2058     prevLinkPtr = n->prevLinkPtr;
2059     unitNo = n->unitNo;
2060     specialNetworkType = n->specialNetworkType;
2061     TopoSortID = n->TopoSortID;
2062     no_of_topo_units = n->no_of_topo_units;
2063 }
2064 
2065 
2066 
2067 /*****************************************************************************
2068   FUNCTION : krm_getPattern
2069 
2070   PURPOSE  : Receiving a pattern set from the Enzo  manager modul
2071 
2072   RETURNS  :
2073   NOTES    : This is just a dummy function
2074 
2075   UPDATE   :
2076 ******************************************************************************/
krm_getPattern(memPat * p)2077 void krm_getPattern( memPat *p )
2078 {
2079 
2080 }
2081 
2082 
2083 
2084 /*****************************************************************************
2085   FUNCTION : krm_putPattern
2086 
2087   PURPOSE  : Receiving a pattern set back under the control of the Enzo
2088              manager modul
2089   RETURNS  :
2090   NOTES    :
2091 
2092   UPDATE   :
2093 ******************************************************************************/
krm_putPattern(memPat * p)2094 void krm_putPattern( memPat *p )
2095 {
2096     static int in[MAX_NO_OF_VAR_I_DIM],out[MAX_NO_OF_VAR_I_DIM];
2097 
2098     krui_setCurrPatSet( p->number );
2099     in[0] = 1; /*krui_getNoOfInputUnits();*/
2100     in[1] = 1;
2101     out[0] = 1; /*krui_getNoOfOutputUnits();*/
2102     out[1] = 1;
2103     krui_DefTrainSubPat(in, out, in, out,NULL);
2104 }
2105 
2106 #endif
2107