constblock memory stuff

added condump, dumps current console contents to file


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1347 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
TimeServ 2005-09-21 01:14:04 +00:00
parent 21d035d4cc
commit b63737c08b
5 changed files with 308 additions and 8 deletions

View File

@ -497,8 +497,7 @@ void Cmd_Exec_f (void)
else
{
Con_TPrintf (TL_EXECFAILED,name);
return;
}
return; }
if (cl_warncmd.value || developer.value)
Con_TPrintf (TL_EXECING,name);
@ -2734,6 +2733,72 @@ void Cmd_WriteConfig_f(void)
fclose(f);
}
#ifndef SERVERONLY
// dumps current console contents to a text file
void Cmd_Condump_f(void)
{
FILE *f;
char *filename;
if (!con_current)
{
Con_Printf ("No console to dump.\n");
return;
}
if (Cmd_IsInsecure()) // don't allow insecure level execute this
return;
filename = Cmd_Argv(1);
if (!*filename)
filename = "condump";
filename = va("%s/%s", com_gamedir, filename);
COM_DefaultExtension(filename, ".txt");
f = fopen (filename, "wb");
if (!f)
{
Con_Printf ("Couldn't write console dump %s\n",filename);
return;
}
// print out current contents of console
// stripping out starting blank lines and blank spaces
{
unsigned short *text;
int row, line, x, spc, content;
console_t *curcon = &con_main;
content = 0;
row = curcon->current - curcon->totallines+1;
for (line = 0; line < curcon->totallines-1; line++, row++)
{
text = curcon->text + (row % curcon->totallines)*curcon->linewidth;
spc = 0;
for (x = 0; x < curcon->linewidth; x++)
{
if (((qbyte)text[x]&255) == ' ')
spc++;
else
{
content = 1;
for (; spc > 0; spc--)
fprintf(f, " ");
fprintf(f, "%c", (qbyte)text[x]&255);
}
}
if (content)
fprintf(f, "\n");
}
}
fclose(f);
Con_Printf ("Dumped console to %s\n",filename);
}
#endif
/*
============
Cmd_Init
@ -2754,6 +2819,7 @@ void Cmd_Init (void)
Cmd_AddCommand ("wait", Cmd_Wait_f);
#ifndef SERVERONLY
Cmd_AddCommand ("cmd", Cmd_ForwardToServer_f);
Cmd_AddCommand ("condump", Cmd_Condump_f);
#endif
Cmd_AddCommand ("restrict", Cmd_RestrictCommand_f);
Cmd_AddCommand ("aliaslevel", Cmd_AliasLevel_f);
@ -2775,6 +2841,7 @@ void Cmd_Init (void)
Cmd_AddCommand ("cvarlist", Cvar_List_f);
Cmd_AddCommand ("cvarreset", Cvar_Reset_f);
Cmd_AddCommand ("fs_flush", COM_RefreshFSCache_f);
Cvar_Register(&com_fs_cache, "Filesystem");
Cvar_Register(&tp_disputablemacros, "Teamplay");

View File

@ -26,6 +26,57 @@ cvar_group_t *cvar_groups;
//cvar_t *cvar_vars;
char *cvar_null_string = "";
cvar_const_cache_t cc_cache;
// cvar string cache functions
// CCC_AddString: adds a string into the cvar CB, and creates one
// if non-existant
char *CCC_AddString(char *s)
{
int size = strlen(s) + 1;
if (!cc_cache.cb)
cc_cache.cb = CB_Malloc(CC_CACHE_SIZE, CC_CACHE_STEP);
return CB_Copy (cc_cache.cb, s, size);
}
// CCC_CheckAndAddString: checks against the CCC table, updates table,
// and either adds or returns cached string
char *CCC_CheckAndAddString(char *s)
{
int i;
char *c;
for (i = 0; i < CC_CACHE_ENTRIES; i++)
{
if (cc_cache.cached[i] && !strcmp(s, cc_cache.cached[i]))
{
// move string to top, pushing others down
c = cc_cache.cached[i];
if (i != 0)
{
Q_memcpy(cc_cache.cached + 1,
cc_cache.cached,
sizeof(char*) * i);
cc_cache.cached[0] = c;
}
return c;
}
}
// not in cache, so add it to table
// move current cached strings down
Q_memcpy(cc_cache.cached + 1,
cc_cache.cached,
sizeof(char*) * (CC_CACHE_ENTRIES - 1));
return (cc_cache.cached[0] = CCC_AddString(s));
}
/*
============
Cvar_FindVar
@ -774,7 +825,7 @@ void Cvar_Free(cvar_t *tbf)
}
unlinked:
Z_Free(tbf->string);
Z_Free(tbf->defaultstr);
// Z_Free(tbf->defaultstr);
if (tbf->latched_string)
Z_Free(tbf->latched_string);
Z_Free(tbf);
@ -816,8 +867,7 @@ void Cvar_Register (cvar_t *variable, const char *groupname)
variable->string = (char*)Z_Malloc (1);
//cheat prevention - engine set default is the one that stays.
variable->defaultstr = (char*)Z_Malloc (strlen(value)+1); //give it it's default (for server controlled vars and things)
strcpy (variable->defaultstr, value);
variable->defaultstr = CCC_CheckAndAddString(value); //give it it's default (for server controlled vars and things)
// set it through the function to be consistant
if (old->latched_string)
@ -849,8 +899,7 @@ void Cvar_Register (cvar_t *variable, const char *groupname)
variable->string = (char*)Z_Malloc (1);
variable->defaultstr = (char*)Z_Malloc (strlen(value)+1); //give it it's default (for server controlled vars and things)
strcpy (variable->defaultstr, value);
variable->defaultstr = CCC_CheckAndAddString(value); //give it it's default (for server controlled vars and things)
// set it through the function to be consistant
Cvar_SetCore (variable, value, true);
@ -1059,4 +1108,6 @@ void Cvar_Shutdown(void)
cvar_groups = grp->next;
Z_Free(grp);
}
CB_Free(cc_cache.cb);
}

View File

@ -146,3 +146,14 @@ void Cvar_Shutdown(void);
void Cvar_ForceCheatVars(qboolean semicheats, qboolean absolutecheats); //locks/unlocks cheat cvars depending on weather we are allowed them.
//extern cvar_t *cvar_vars;
// cvar const cache, used for removing fairly common default cvar values
#define CC_CACHE_ENTRIES 8
#define CC_CACHE_SIZE 2048
#define CC_CACHE_STEP 2048
typedef struct cvar_const_cache_s {
char *cached[CC_CACHE_ENTRIES];
const_block_t *cb;
} cvar_const_cache_t;

View File

@ -409,6 +409,73 @@ void BZ_Free(void *data)
Z_Free(data);
}
#ifdef NAMEDMALLOCS
// Zone_Groups_f: prints out zones sorting into groups
// and tracking number of allocs and total group size as
// well as a group delta against the last Zone_Group_f call
#define ZONEGROUPS 64
void Zone_Groups_f(void)
{
zone_t *zone;
char *zonename[ZONEGROUPS];
int zonesize[ZONEGROUPS];
int zoneallocs[ZONEGROUPS];
static int zonelast[ZONEGROUPS];
int groups, i;
int allocated = 0;
// initialization
for (groups = 0; groups < ZONEGROUPS; groups++)
zonename[groups] = NULL;
groups = 0;
i = 0;
for (zone = zone_head; zone; zone=zone->next)
{
char *czg = (char *)(zone+1) + zone->size+ZONEDEBUG*2;
// check against existing tracked groups
for (i = 0; i < groups; i++)
{
if (!strcmp(czg, zonename[i]))
{
// update stats for tracked group
zonesize[i] += zone->size;
zoneallocs[i]++;
break;
}
}
if (groups == i) // no existing group found
{
// track new zone group
zonename[groups] = czg;
zonesize[groups] = zone->size;
zoneallocs[groups] = 1;
groups++;
// max groups bounds check
if (groups >= ZONEGROUPS)
{
groups = ZONEGROUPS;
break;
}
}
}
// print group statistics
for (i = 0; i < groups; i++)
{
allocated += zonesize[i];
Con_Printf("%s, size: %i, allocs: %i, delta: %i\n", zonename[i], zonesize[i], zoneallocs[i], zonesize[i] - zonelast[i]);
zonelast[i] = zonesize[i]; // update delta tracking for next call
}
Con_Printf("Total: %i bytes\n", allocated);
}
#endif
void Zone_Print_f(void)
{
int overhead=0;
@ -430,7 +497,7 @@ void Zone_Print_f(void)
}
else
#endif
if (*Cmd_Argv(1) == 'h')
if (*Cmd_Argv(1) == 'h')
futurehide = true;
else if (*Cmd_Argv(1))
minsize = atoi(Cmd_Argv(1));
@ -1396,6 +1463,9 @@ void Cache_Init(void)
Cmd_AddCommand ("flush", Cache_Flush);
Cmd_AddCommand ("hunkprint", Hunk_Print_f);
Cmd_AddCommand ("zoneprint", Zone_Print_f);
#ifdef NAMEDMALLOCS
Cmd_AddCommand ("zonegroups", Zone_Groups_f);
#endif
}
#else
@ -1755,6 +1825,92 @@ void *Cache_Alloc (cache_user_t *c, int size, char *name)
#endif
//============================================================================
// Constant block functions
// CB_Malloc: creates a usable const_block
const_block_t *CB_Malloc (int size, int step)
{
// alloc new const block
const_block_t *cb = Z_Malloc(sizeof(const_block_t));
// init cb members
cb->block = BZ_Malloc(size);
cb->point = cb->block;
cb->curleft = size;
cb->cursize = size;
cb->memstep = step;
return cb;
}
// CB_Slice: slices a chunk of memory off of the const block, and
// reallocs if necessary
char *CB_Slice (const_block_t *cb, int size)
{
char *c;
while (size > cb->curleft)
{
cb->block = BZ_Realloc(cb->block, cb->cursize + cb->memstep);
cb->point = cb->block + (cb->cursize - cb->curleft);
cb->cursize += cb->memstep;
cb->curleft += cb->memstep;
}
c = cb->point;
cb->point += size;
cb->curleft -= size;
return c;
}
// CB_Copy: copies a stream of bytes into a const block, returns
// pointer of copied string
char *CB_Copy (const_block_t *cb, char *data, int size)
{
char *c;
c = CB_Slice(cb, size);
Q_memcpy(c, data, size);
return c;
}
// CB_Free: frees a const block
void CB_Free (const_block_t *cb)
{
BZ_Free(cb->block);
Z_Free(cb);
}
#if 0
// CB_Reset: resets a const block to size
void CB_Reset (const_block_t *cb, int size)
{
if (cb->cursize != size)
{
cb->block = BZ_Realloc(cb->block, size);
cb->cursize = size;
}
cb->point = cb->block;
cb->curleft = cb->cursize;
}
// CB_Trim: trims a const block to minimal size
void CB_Trim (const_block_t *cb)
{
if (cb->curleft > 0)
{
cb->cursize -= cb->curleft;
cb->block = BZ_Realloc(cb->block, cb->cursize);
cb->point = cb->block + cb->cursize;
}
cb->curleft = 0;
}
#endif
/*
========================

View File

@ -156,5 +156,20 @@ void *Cache_Alloc (cache_user_t *c, int size, char *name);
void Cache_Report (void);
// Constant Block memory functions
// - Constant blocks are used for loads of strings/etc that
// are allocated once and change very little during the rest
// of run time, such as cvar names and default values
typedef struct const_block_s {
int curleft; // current bytes left in block
int cursize; // current maximum size of block
int memstep; // bytes to step per realloc
char *point; // current block point
char *block; // memory block
} const_block_t;
const_block_t *CB_Malloc (int size, int step);
//char *CB_Slice (const_block_t *cb, int size);
char *CB_Copy (const_block_t *cb, char *data, int size);
void CB_Free (const_block_t *cb);