コード例 #1
0
ファイル: ssm.c プロジェクト: hadigsf/Assault-3.0
char *_str_dup(const char *str, const char *caller)
{
    BufEntry *ptr;
    int len;
    int rlen;
    char *str_new;

    ssm_dup_count++;
    ssm_recent_loops=0;

    if (!str || !*str)
        return &str_empty[0];

    if (str > string_space && str < top_string)
    {
        ptr = (BufEntry *) (str - HEADER_SIZE);
        if (ptr->usage <= 0)
        {
            bugf("str_dup: invalid string from %s: %20.20s",
                 caller, str);
            ptr->usage=0;                                   /* make it valid again */
        }

        ptr->usage++;
        return (char *) str;
    }

    rlen = len = (int) strlen(str) + 1;

    /*
     * Round up to machine dependant address size.
     * Don't remove this, because when the BufEntry struct is overlaid
     * the struct must be aligned correctly.
     */

    if ((len + HEADER_SIZE) & addrSizeMask)
        len += addrTypeSize - ((len + HEADER_SIZE) & addrSizeMask);

RETRY:
    for (ptr = ssm_buf_free; ptr; ptr = ptr->next)
    {
        ssm_recent_loops++;
        ssm_loops++;
        if (ptr->usage == 0 && ptr->size >= len)
            break;
    }

    if (ptr)
        ptr->usage = 1;

    if (!ptr)
    {
        if (numFree > 1)
            numFree++;

        if (numFree >= MAX_FREE)
        {
            int merges;
            log_f("SSM: Attempting to optimize shared string heap.");
            merges = defrag_heap();

            /* goto is fine because defrag will return 0 next time */
            if (merges)
                goto RETRY;
        }

        /* A one time toggle just for bugging purposes */
        if (!Full)
        {
            bugf("SSM: The shared string heap is full!");
            Full = 1;
        }

        str_new = (char *) malloc(rlen);
        strcpy(str_new, str);
        sOverFlowString += rlen;
        nOverFlowString++;
        if (sOverFlowString > hwOverFlow)
            hwOverFlow=sOverFlowString;
        return str_new;
    }
    /* If there is at least header size excess break it up */
    else if (ptr->size - len >= (HEADER_SIZE+8))
    {
        BufEntry *temp;
        /* WARNING! - DONT REMOVE THE CASTS BELOW! - Fusion */
        temp = (BufEntry *) ((char *) ptr + HEADER_SIZE + len);
        temp->size = ptr->size - (len + HEADER_SIZE);
        temp->next = ptr->next;
        temp->usage = 0;
        ptr->size = len;
        ptr->next = temp;

        ssm_buf_free = temp;
    }
    else
    {
        if (ptr != ssm_buf_free)
            ssm_buf_free->usage--;                          /* buf_free was skipped */

        /* spec: don't start from the start of the heap again! */
        for ( ; ssm_buf_free; ssm_buf_free = ssm_buf_free->next)
        {
            ssm_loops++;
            ssm_recent_loops++;
            if (ssm_buf_free->usage == 0)
                break;
        }
    }

    str_new = (char *) &ptr->buf[0];
    strcpy(str_new, str);
    ptr->caller=caller;
    nAllocString++;
    sAllocString += ptr->size + HEADER_SIZE;

    return str_new;
}
コード例 #2
0
ファイル: string.c プロジェクト: Xangis/ModernMUDConverter
/*
 * Dup a string into shared space. If string exists, the usage count
 * gets incremented and the reference is returned. If the string does
 * not exist in heap, space is allocated and usage is 1.
 * This is a linked list first fit algorithm, so strings can be
 * freed. Upon bootup, there is a seperate hash table constructed in order
 * to do crunching, then the table is destroyed.
 */
char *str_dup( const char *str )
{
    BufEntry *ptr;
    char     *str_new;
    int       len;
    int       rlen;

    if( !str || !*str )
        return &str_empty[0];

    // See if we've already got the string we're looking for
    // if so, return a pointer to that string.
    if( str > string_space && str < top_string )
    {
	ptr = (BufEntry *)( str - HEADER_SIZE );
	if( ptr->usage <= 0 )
	{
	    bug( "str_dup : invalid str", 0 );
	    bug( str, 0 );
	}

	ptr->usage++;
	return (char *)str;
    }

    // Rlen, for required length - we need an extra char for the '\0'.
    rlen = len = (int)strlen( str ) + 1;

    // Round up to machine dependant address size.
    // Don't remove this, because when the BufEntry struct is overlaid
    // the struct must be aligned correctly.
    if( ( len + HEADER_SIZE ) & addrSizeMask ) 
        len += addrTypeSize - ( ( len + HEADER_SIZE ) & addrSizeMask );

    // Do we have room in the shared string buffer?
    if( ssm_buf_free )
    { 
        RETRY:
	for( ptr = ssm_buf_free; ptr; ptr = ptr->next )
	    if( ptr->usage == 0 && ptr->size >= len )
	        break;

        // If we didn't find a large enough hunk available in the open space,
        // try to call defrag_heap() to compress the space in the hopes we'll
        // have room for our string once we're compressed things.
	if( !ptr )
	{
	    if( numFree >= MAX_FREE )
	    {
		int merges;

		bug( "[SSM] Attempting to optimize shared string heap.", 0 );
		merges = defrag_heap();

		// goto is fine because defrag will return 0 next time
		if( merges )
		    goto RETRY;
	    }	

            // I guess it's just too large for our heap.  It gets to sleep in the yard.
	    str_new = (char *)malloc( rlen );
	    strcpy( str_new, str ); 
	    sOverFlowString += rlen;
	    nOverFlowString++;
	    return str_new;
	}
	// We found a place to put our string.
        // If there is at least header size excess break it up
	else if( ptr->size - len >= HEADER_SIZE ) 
	{
	    BufEntry *temp;

	    // WARNING! - DONT REMOVE THE CASTS BELOW! - Fusion
	    temp = (BufEntry*)( (char *)ptr + HEADER_SIZE + len );
	    temp->size   = ptr->size - ( len + HEADER_SIZE );
	    temp->next   = ptr->next;
	    temp->usage  = 0;
	    ptr->size    = len;
	    ptr->next    = temp;
	    ptr->usage   = 1;
	    ssm_buf_free = temp;
	}
	else
	{
	    ptr->usage = 1;
	    if( ptr != ssm_buf_free )
	        ssm_buf_free->usage--; // buf_free was skipped

	    for( ssm_buf_free = ssm_buf_head; ssm_buf_free;
		ssm_buf_free = ssm_buf_free->next )
	        if( ssm_buf_free->usage == 0 )
		    break;
	}

	str_new = (char *)&ptr->buf[0];
	strcpy( str_new, str ); 
	nAllocString++;
	sAllocString += ptr->size + HEADER_SIZE;
    }
    else  
    {
	// A one time toggle just for bugging purposes
	if( !Full )
	{
	    bug( "[SSM] The shared string heap is full!", 0 );
	    Full = 1;
	}

        // And we let our string sleep in the yard.
	str_new = (char *)malloc( rlen );
	strcpy( str_new, str ); 
	sOverFlowString += rlen;
	nOverFlowString++;
    } 

    return str_new;
}
コード例 #3
0
ファイル: ssm.c プロジェクト: janvandijk/muds
/*
 * Dup a string into shared space. If string exists, the usage count
 * gets incremented and the reference is returned. If the string does
 * not exist in heap, space is allocated and usage is 1.
 * This is a linked list first fit algorithm, so strings can be
 * freed. Upon bootup, there is a seperate hash table constructed in order
 * to do crunching, then the table is destroyed.
 */
char *str_dup( const char *str )
{
    BufEntry *ptr;
    char     *str_new;
    int       len;
    int       rlen;

    if( !str || !*str )
        return &str_empty[0];

    if( str > string_space && str < top_string )
    {
	ptr = (BufEntry *)( str - HEADER_SIZE );
	if( ptr->usage <= 0 )
	{
	    bug( "str_dup : invalid str", 0 );
	    bug( str, 0 );
	}

	ptr->usage++;
	return (char *)str;
    }

    rlen = len = (int)strlen( str ) + 1;

    /* 
     * Round up to machine dependant address size.
     * Don't remove this, because when the BufEntry struct is overlaid
     * the struct must be aligned correctly.
     */

    if( ( len + HEADER_SIZE ) & addrSizeMask ) 
        len += addrTypeSize - ( ( len + HEADER_SIZE ) & addrSizeMask );

    if( ssm_buf_free )
    { 
        RETRY:
	for( ptr = ssm_buf_free; ptr; ptr = ptr->next )
	    if( ptr->usage == 0 && ptr->size >= len )
	        break;

	if( !ptr )
	{
	    if( numFree >= MAX_FREE )
	    {
		int merges;

		bug( "[SSM] Attempting to optimize shared string heap.", 0 );
		merges = defrag_heap();

		/* goto is fine because defrag will return 0 next time */
		if( merges )
		    goto RETRY;
	    }	

	    str_new = (char *)malloc( rlen );
	    strcpy( str_new, str ); 
	    sOverFlowString += rlen;
	    nOverFlowString++;
	    return str_new;
	}

	/* If there is at least header size excess break it up */
	else if( ptr->size - len >= HEADER_SIZE ) 
	{
	    BufEntry *temp;

	    /* WARNING! - DONT REMOVE THE CASTS BELOW! - Fusion */
	    temp = (BufEntry*)( (char *)ptr + HEADER_SIZE + len );
	    temp->size   = ptr->size - ( len + HEADER_SIZE );
	    temp->next   = ptr->next;
	    temp->usage  = 0;
	    ptr->size    = len;
	    ptr->next    = temp;
	    ptr->usage   = 1;
	    ssm_buf_free = temp;
	}
	else
	{
	    ptr->usage = 1;
	    if( ptr != ssm_buf_free )
	        ssm_buf_free->usage--; /* buf_free was skipped */

	    for( ssm_buf_free = ssm_buf_head; ssm_buf_free;
		ssm_buf_free = ssm_buf_free->next )
	        if( ssm_buf_free->usage == 0 )
		    break;
	}

	str_new = (char *)&ptr->buf[0];
	strcpy( str_new, str ); 
	nAllocString++;
	sAllocString += ptr->size + HEADER_SIZE;
    }
    else  
    {
	/* A one time toggle just for bugging purposes */
	if( !Full )
	{
	    bug( "[SSM] The shared string heap is full!", 0 );
	    Full = 1;
	}

	str_new = (char *)malloc( rlen );
	strcpy( str_new, str ); 
	sOverFlowString += rlen;
	nOverFlowString++;
    } 

    return str_new;
}