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