MAILING #2 -=- New String Manager for Envy (and Merc) -=- Replacement code for : str_dup(), free_string(), fread_string() The new functions are in ssm.c, or you may be extracting it from mail so name it what you want. - Edit the Makefile and add ssm.o Two files need to be modified : db.c, save.c <<<<< db.c >>>>> ---- (1) - Comment out the functions str_dup(), free_string(), and fread_string() fread_string has comments so be careful to comment in blocks (2) - Add the function prototypes for init_string_space() and boot_done() to the Semi-locals. - string search for 'Semi-loc' Also add extern for MAX_STRING which is no lonfer a #define Add lines: =========== extern int MAX_STRING; void init_string_space args( ( void ) ); void boot_done args( ( void ) ); =========== You can now remove MAX_STRING #define and string_hash table. Line 189 or so: REMOVE =========== #define MAX_STRING 150000 =========== Line 164 or so: REMOVE =========== char * string_hash [ MAX_KEY_HASH ]; =========== Or you may want to keep them in case you decide to go back to old code (If you do you're nuts :P) (3) - Go to boot_db() , the first thing in boot_db() is where the read-only string space is calloc'd : =========== /* * Init some data space stuff. */ { > if ( !( string_space = calloc( 1, MAX_STRING ) ) ) > { > bug( "Boot_db: can't alloc %d string space.", MAX_STRING ); > exit( 1 ); > } > top_string = string_space; fBootDb = TRUE; } =========== Changes to: =========== /* * Init some data space stuff. */ { PATCH> init_string_space(); fBootDb = TRUE; } =========== init_string_space() either succeeds or exits. Now somewhere around line 400: This is where we declare booting over, set fBootDb to FALSE, etc. fix_exits( ); fBootDb = FALSE; PATCH> boot_done( ); /* ssm.c destroys the boot hash table */ area_update( ); boot_done() destroys the temp boot hash table. This table is created to allow fast referencing of strings for crunching the string space. Every string is searched for on bootup and all identical strings are combined to save RAM. This temporary hash table is vital since the heap is a linked-list first fit algorithm. Without the hash table you either get 2 minute boot times or larger heap. (4) - Now we have the functions in place. There are still some reliances on strings never being freed. Functions like create_mobile() just assign the pointers instead of calling str_dup(). That USED to be OK but now the str_dup() is real so we have to call it. All this really does is updates the usage counter on the string so it won't be freed with references still pointing to it. fread_string() is fine since the new fread_string() returns a str_dup'd string. First in create_mobile(): =========== > mob->name = pMobIndex->player_name; > mob->short_descr = pMobIndex->short_descr; > mob->long_descr = pMobIndex->long_descr; > mob->description = pMobIndex->description; =========== changes to str_dup's =========== mob->name = str_dup( pMobIndex->player_name ); mob->short_descr = str_dup( pMobIndex->short_descr ); mob->long_descr = str_dup( pMobIndex->long_descr ); mob->description = str_dup( pMobIndex->description ); =========== Then in create_object(): =========== > obj->name = pObjIndex->name; > obj->short_descr = pObjIndex->short_descr; > obj->description = pObjIndex->description; =========== changes to str_dup's =========== obj->name = str_dup( pObjIndex->name ); obj->short_descr = str_dup( pObjIndex->short_descr ); obj->description = str_dup( pObjIndex->description ); =========== Since my manager doesn't do hashing after bootup to merge matching strings, there is another loose end. The mob prompts are str_dup'd from a const char string which creates new space every time so we need to create a global pointer to a str_dup'd mob prompt and in every create_mobile, str_dup the pointer rather than a const string. This is not required but it saves 50k on bootup and even more when mobs start growing. This was not needed with Furey's code since it does hashing and always looks for matches. Somewhere in db.c (mine is right below the declaration for str_empty[1]) we add a global char *: Around line 175: PATCH> char * mobPrompt; Now add the str_dup in boot_db)() Around line 416: > load_notes( ); > load_down_time( ); PATCH> mobPrompt = str_dup( "<%hhp %mm %vmv> " ); Then in create_mobile change the prompt creation from: mob->prompt = str_dup( "<%hhp %mm %vmv> " ); To: PATCH> mob->prompt = str_dup( mobPrompt ); NOTE: In ssm.c you probably need to tweak MAX_STRING some. I set it to 1700000 because not only does my code take a little more space on the heap but it is can now be used in place of the real C strdup() so leave some work space. <<< save.c >>> fread_obj() at line 825 of save.c of Envy_1.0 In the block where we read the "End" string of the current object, compare the strings to the index. If they are identical then free the obj-><str> and str_dup the obj->pIndexData-><str> Add it after line 825. (or whatver yours is) Line 825: obj->pIndexData->count++; > if ( !strcmp( obj->name, obj->pIndexData->name ) ) > { > free_string( obj->name ); > obj->name = str_dup( obj->pIndexData->name ); > } > if ( !strcmp( obj->short_descr, obj->pIndexData->short_descr ) ) > { > free_string( obj->short_descr ); > obj->short_descr = str_dup( obj->pIndexData->short_descr ); > } > if ( !strcmp( obj->description, obj->pIndexData->description ) ) > { > free_string( obj->description ); > obj->description = str_dup( obj->pIndexData->description ); > } That should save some mem especially if your mud allows packratting. After recompile type 'mem' in the game. Your perm count should be lower and string count should be almost identical to the old code. -==- This is all that needs to be changed in the base Envy and it should be identical for Merc. I have no idea what ROM's string code is like so I can't say, but if it is the standard no-freeing Merc code then you may want to think about adding my patch. Using OLC now should have no bearing on the runtime (gradual buildup of read-only strings). The latest version of ssm.c should be with Jason Dinkel's ILAB OLC. Let me know if you have problems or if I missed something. Lost Realms has been running for 3 months with this code and OLC with no problems. Fusion msmith@falcon.mercer.peachnet.edu