/*{{{ comment*/ /* File names.c This module contains functions to move from i860 pointer <--> i860 name This is primarily for SuperVision distributed rendering systems where the same data item will be held in different places on different boards Phil Atkin (c) Division Ltd. 1991 */ /*}}} */ /*{{{ discussion*/ /* In superVision we have a problem that the same data item will not appear in the same place on different processors. We need to implement a naming system which allows us to uniquely identify a piece of data and find its location in memory. There are two strategies for this - we either try to maintain as many REAL pointers as we can in the i860 and resort to names only across the dView/i860 boundary, OR we swallow the big pill and use names EVERYWHERE, including the internal linked lists. Currently we load no more than 400 instances (the corridor maze demo). If I build a hash table of 512 locations, at the moment no programs will need to indirect more than once to get the physical location from the name. OK, that's decided it - ALL references to dView-visible items will be by NAME. Internal linked lists will be maintained as pointers. The dpl processor ignores the NEXT field anyway, so the only problem then is heirarchy. IMPACTS ------- Backward compatibility ---------------------- NULL needs to be an invalid name. Walking linked lists, we need to go nameToAddress() on each item. heirachy -------- In heirarchies, the link, next and daddy fields are NAMES. Therefore heirarchy stuff needs nameToAddress() in the loop. Creation -------- We get a new name. Add it to the hash table, and hand the pointer back to the dView. Deletion -------- Do what we do now, but in addition delete any hash-table storage. I believe we NEVER need to go addressToName() */ /*}}} */ /*{{{ includes*/ #include #include #include #include "dpltypes.h" /*}}} */ /*{{{ local typedefs*/ #define max_pages 512 #define mask_pages ((max_pages)-1) typedef struct s_ypage { struct s_ypage *next; int name; dpl_type name_type; void *address; } yellowPage; /*}}} */ /*{{{ statics*/ static yellowPage *yellowPages [max_pages]; static int init=0; /*}}} */ /*{{{ externally visible*/ /* the first name handed out is 1 */ int allocatedNames=1; /*}}} */ /*{{{ void checkNull ( void *p, char *s )*/ void checkNull ( void *p, char *s ) { if (p==NULL) { printf( "NULL pointer in %s\n", s ); fflush(stdout); exit (666); } /* else printf ( "ok pointer in %s\n", s ); */ } /*}}} */ /*{{{ int initNames ()*/ int initNames () { int i; /* printf ("initNames\n"); */ if (init==0) { for (i=0; iaddress=location; head->name=item_name; head->name_type=type; head->next=NULL; yellowPages[item_name&mask_pages] = head; } else { /* find tail of list */ while (node->next != NULL) { node=node->next; } node->next=(yellowPage *) malloc ( sizeof (yellowPage)); node=node->next; checkNull ( node, "createName"); node->address=location; node->name=item_name; node->name_type=type; node->next=NULL; } /* printf ("newName returning %d\n", item_name ); */ return ( item_name ); } /*}}} */ /*{{{ int newName ( void *location, dpl_type type )*/ int newName ( void *location, dpl_type type ) { /* printf ("newName %d\n", item_name ); */ if (location == NULL) return 0; else { int item_name=allocatedNames++; addName ( item_name, location, type ); return ( item_name ); } } /*}}} */ /*{{{ int deleteName ( int item_name, dpl_type type )*/ int deleteName ( int item_name, dpl_type type ) { yellowPage *head=yellowPages[item_name&mask_pages], *node=head, *prev=NULL; while (node->name != item_name) { prev=node; node=node->next; if (node==NULL) { printf ("Name 0x%x (%s) not found\n", item_name, type_to_string(type) ); exit (666); } } if (type != (-1)) { if (node->name_type != type ) { printf ("deleteName: name 0x%x wrong type, expected %s found %s\n", item_name, type_to_string(type), type_to_string(node->name_type) ); exit (666); } } if (prev == NULL) { yellowPages[item_name&mask_pages] = node->next; free ( node ); } else { prev->next=node->next; free (node); } } /*}}} */ /*{{{ void *nameToAddress ( int item_name, dpl_type type )*/ void *nameToAddress ( int item_name, dpl_type type ) { yellowPage *head; if (item_name == 0) return NULL; for (head=yellowPages[item_name&mask_pages];head;head=head->next) { if (head->name == item_name) { if (head->name_type == type) { return head->address; } else if (type == (dpl_type) (-1)) { return head->address; } else { printf ("nameToAddress: name 0x%x wrong type, expected %s found %s address 0x%x\n", item_name, type_to_string(type), type_to_string(head->name_type), head->address); printf ("allocatedNames = %d\n", allocatedNames ); return NULL; } } } return NULL; } /*}}} */ /*{{{ int addressToName ( void *item, dpl_type type )*/ int addressToName ( void *item, dpl_type type ) { int i; for (i=0; i<(mask_pages)+1; i++ ) { yellowPage *head=yellowPages[i]; while (head) { if (head->address == item) { if (type == (-1)) return head->name; else if (head->name_type == type) return head->name; else printf ("found item 0x%x name 0x%x, wrong type\n", item, head->name ); } head=head->next; } } return 0; } /*}}} */ /*{{{ int check_name ( int name)*/ int check_name ( int name) { return ((name < 0) || (name > allocatedNames)); } /*}}} */