• MemMan 3 beta 5


    /**************************************************
     *
     * MemMan 3.0.0.0 beta
     *
     * Copyright (C) 2007 - 2008 by Len3d
     * All rights reserved.
     *
     ************************************************
    */


    #ifndef __MEMMAN__
    #define __MEMMAN__

    #include 
    <malloc.h>
    #include 
    <vector>
    #include 
    <algorithm>
    #include 
    <iostream>

    #pragma pack(push,
    1)

    namespace mem {

        
    #define mem_inline        __forceinline

        
    #define mem_pool_pad    16    
        
    #define mem_page_pad    48
        
    #define    mem_page_size    ( 2 << 18 )
        
    #define mem_align_size    16
        
    #define mem_align        __declspec( align( mem_align_size ) )

        typedef unsigned 
    int    prior_type;
        typedef unsigned 
    long    time_type;
        typedef unsigned 
    long    size_type;
        typedef unsigned 
    char    byte;

        
    #define mem_max( a, b )    ( ( (a) > (b) ) ? (a) : (b) )
        
    #define mem_min( a, b )    ( ( (a) < (b) ) ? (a) : (b) )
        
    #define mem_mbyte( a )    ( float(a) * (1.0f / float( 1024 * 1024 )) )

        
    enum {
            ENTRY_PRIORITY 
    = 0,
        }
    ;

        
    extern time_type    num_stream_out;

        
    class heap {
        
    public:
            mem_inline heap( size_type max_size )
            
    {
                allocated_size 
    = 0;
                available_size 
    = max_size;
            }


            mem_inline 
    ~heap()
            
    {
            }


            mem_inline 
    void *alloc( size_type size )
            
    {
                
    if( size == 0 )
                    
    return NULL;

                allocated_size 
    += size;
                available_size 
    -= size;

                
    return sys_alloc( size );
            }


            mem_inline 
    void dealloc( void *ptr, size_type size )
            
    {
                
    if( ptr && size != 0 )
                
    {
                    sys_dealloc( ptr );

                    allocated_size 
    -= size;
                    available_size 
    += size;
                }

            }


            mem_inline 
    void *aligned_alloc( size_type size )
            
    {
                
    if( size == 0 )
                    
    return NULL;

                allocated_size 
    += size;
                available_size 
    -= size;

                
    return sys_aligned_alloc( size );
            }


            mem_inline 
    void aligned_dealloc( void *ptr, size_type size )
            
    {
                
    if( ptr && size != 0 )
                
    {
                    sys_aligned_dealloc( ptr );

                    allocated_size 
    -= size;
                    available_size 
    += size;
                }

            }


            mem_inline size_type available() 
    const
            
    {
                
    return available_size;
            }


            mem_inline 
    void print()
            
    {
                std::cout 
    << std::endl;
                std::cout 
    << "========== heap Statistics ==========" << std::endl;
                std::cout 
    << std::endl;

                std::cout 
    << "allocated size: " << mem_mbyte( allocated_size ) << " MB" << std::endl;
                std::cout 
    << "available size: " << mem_mbyte( available_size ) << " MB" << std::endl;

                std::cout 
    << std::endl;
                std::cout 
    << "=====================================" << std::endl;
                std::cout 
    << std::endl;
            }


        
    private:
            mem_inline 
    void *sys_alloc( size_type size )
            
    {
                
    return malloc( size );
            }


            mem_inline 
    void sys_dealloc( void *ptr )
            
    {
                free( ptr );
            }


            mem_inline 
    void *sys_aligned_alloc( size_type size )
            
    {
                
    return _aligned_malloc( size, mem_align_size );
            }


            mem_inline 
    void sys_aligned_dealloc( void *ptr )
            
    {
                _aligned_free( ptr );
            }


        
    private:
            size_type        allocated_size, 
                            available_size;
        }
    ;
        
        template 
    < typename ALLOC >
        
    class pool {
        
    private:
            
    class page {
            
    public:
                mem_inline page( size_type _size, page 
    *old )
                
    {
                    
    base = get_base();
                    _next 
    = old;
                    size 
    = _size;
                }


                mem_inline 
    byte *get_base()
                
    {
                    
    return ( (byte *this + sizeof(page) );
                }


                mem_inline size_type get_size()
                
    {
                    
    return static_cast<size_type>base - get_base() + size );
                }


                mem_inline size_type available() 
    const
                
    {
                    
    return size;
                }


                mem_inline 
    void *alloc( size_type _size )
                
    {
                    
    byte    *ptr = base;
                    
    base += _size;
                    size 
    -= _size;
                    
    return ptr;
                }


                mem_inline page 
    *next()
                
    {
                    
    return _next;
                }


            
    private:
                mem_align union 
    {
                    
    struct {
                        
    byte            *base;
                        page            
    *_next;
                        size_type        size;
                    }
    ;
                    
    byte    pad[mem_pool_pad];
                }
    ;
            }
    ;

            
    class chunk {
            
    public:
                mem_inline chunk( size_type _size, chunk 
    *old )
                
    {
                    next 
    = old;
                    size 
    = _size;
                }


                mem_inline size_type available() 
    const
                
    {
                    
    return size;
                }


            
    public:
                chunk            
    *next;
                size_type        size;
            }
    ;

        
    public:
            mem_inline pool()
            
    {
                pages 
    = NULL;
                chunks 
    = NULL;
                allocated 
    = 0;
            }


            mem_inline 
    ~pool()
            
    {
                destory();
            }


            mem_inline 
    void destory()
            
    {
                page    
    *p;
            
                
    while( ( p = pages ) != NULL )
                
    {
                    pages 
    = p->next();
                    al.dealloc( p, p
    ->get_size() );
                }


                pages 
    = NULL;
                chunks 
    = NULL;
            }


            mem_inline 
    bool search_chunk( void * & ptr, size_type size )
            
    {
                
    if( chunks && ( size <= chunks->available() ) )
                
    {
                    ptr 
    = (void *) chunks;
                    chunks 
    = chunks->next;

                    
    return true;
                }

                
    else
                    
    return false;
            }


            mem_inline 
    bool search_page( void * & ptr, size_type size )
            
    {
                
    if( pages && ( size <= pages->available() ) )
                
    {
                    ptr 
    = pages->alloc( size );

                    
    return true;
                }

                
    else
                    
    return false;
            }


            mem_inline 
    void allocate_page( size_type size )
            
    {
                size_type    asize 
    = mem_max( size, mem_page_size );

                pages 
    = new (al.alloc( sizeof(page) + asize )) page( asize, pages );
            }


            mem_inline 
    void *alloc( size_type size )
            
    {
                
    void    *ptr;

                
    ++ allocated;

                
    if( search_chunk( ptr, size ) )
                    
    return ptr;
                
    else if( search_page( ptr, size ) )
                    
    return ptr;
                
    else {
                    allocate_page( size );
                    
    if( search_page( ptr, size ) )
                        
    return ptr;
                    
    else
                        
    return NULL;
                }

            }


            mem_inline 
    void dealloc( void *ptr, size_type size )
            
    {
                
    -- allocated;

                
    if( size >= sizeof(chunk) )
                    chunks 
    = new (ptr) chunk( size, chunks );
            
                
    if( allocated == 0 )
                    destory();
            }


            mem_inline 
    void print()
            
    {
                std::cout 
    << std::endl;
                std::cout 
    << "========== pool Statistics ==========" << std::endl;
                std::cout 
    << std::endl;

                std::cout 
    << "number of allocations: " << allocated << std::endl;

                std::cout 
    << std::endl;
                std::cout 
    << "=====================================" << std::endl;
                std::cout 
    << std::endl;
            }


        
    private:
            page            
    *pages;
            chunk            
    *chunks;
            size_type        allocated;
            ALLOC            al;
        }
    ;

        template 
    < typename ALLOC >
        
    class cache {
        
    public:
            
    class node;

            
    class entry {
            
    public:
                mem_inline entry()
                
    {
                    priority 
    = ENTRY_PRIORITY;
                    last_use_time 
    = pl.get_current_time();
                    locked 
    = false;
                    node_ptr 
    = NULL;
                }


                mem_inline entry( prior_type prior )
                
    {
                    priority 
    = prior;
                    last_use_time 
    = pl.get_current_time();
                    locked 
    = false;
                    node_ptr 
    = NULL;
                }

            
                mem_inline 
    virtual ~entry()
                
    {
                }


                mem_inline 
    void *alloc( size_type size )
                
    {
                    
    return pl.alloc( size, this );
                }


                mem_inline 
    void dealloc( void *ptr, size_type size )
                
    {
                    pl.dealloc( ptr, size, 
    this );
                }


                mem_inline 
    void stream_begin()
                
    {
                    locked 
    = true;
                    stream_in();
                    last_use_time 
    = pl.get_current_time();
                }


                mem_inline 
    void stream_end()
                
    {
                    locked 
    = false;
                }


                mem_inline 
    bool is_locked()
                
    {
                    
    return locked;
                }


                mem_inline 
    bool operator < ( const entry & right ) const
                
    {
                    
    if( priority == right.priority )
                        
    return ( last_use_time < right.last_use_time );
                    
    else
                        
    return ( priority < right.priority );
                }


            
    public:
                
    virtual void stream_in() = 0;

                
    virtual size_type stream_size() = 0;

                
    virtual void *stream_out() = 0;

            
    public:
                
    static cache< ALLOC >    pl;
                prior_type                priority;
                time_type                last_use_time;
                
    bool                    locked;
                node                    
    *node_ptr;
            }
    ;

            
    class node {
            
    public:
                mem_inline node( entry 
    *obj, node *old, node *g_old, node *phead, node *g_phead )
                
    {
                    ptr 
    = obj;
                    obj
    ->node_ptr = this;
                    next 
    = old;
                    prev 
    = phead;
                    g_next 
    = g_old;
                    g_prev 
    = g_phead;
                    
    if( next )
                        next
    ->prev = this;
                    
    if( prev )
                        prev
    ->next = this;
                    
    if( g_next )
                        g_next
    ->g_prev = this;
                    
    if( g_prev )
                        g_prev
    ->g_next = this;
                }


                mem_inline node()
                
    {
                    ptr 
    = NULL;
                    next 
    = NULL;
                    prev 
    = NULL;
                    g_next 
    = NULL;
                    g_prev 
    = NULL;
                }


                mem_inline 
    ~node()
                
    {
                    
    void    *= NULL;

                    stream_out( p );
                }


                mem_inline time_type get_last_use_time() 
    const
                
    {
                    
    if( ptr )
                        
    return ptr->last_use_time;
                    
    else
                        
    return 0;
                }


                mem_inline 
    bool is_locked() const
                
    {
                    
    if( ptr )
                        
    return ptr->is_locked();
                    
    else
                        
    return false;
                }


                mem_inline size_type stream_size()
                
    {
                    
    if( ptr )
                        
    return ptr->stream_size();
                    
    else
                        
    return 0;
                }


                mem_inline 
    bool stream_out( void * & p )
                
    {
                    
    if( ptr )
                    
    {
                        p 
    = ptr->stream_out();

                        ptr
    ->node_ptr = NULL;

                        
    ++ num_stream_out;

                        
    return true;
                    }

                    
    else
                        
    return false;
                }


                mem_inline 
    void detach()
                
    {
                    
    if( prev )
                        prev
    ->next = next;
                    
    if( next )
                        next
    ->prev = prev;
                }


                mem_inline 
    void g_detach()
                
    {
                    
    if( g_prev )
                        g_prev
    ->g_next = g_next;
                    
    if( g_next )
                        g_next
    ->g_prev = g_prev;
                }


            
    public:
                entry        
    *ptr;
                node        
    *next, *prev;
                node        
    *g_next, *g_prev;
            }
    ;

            
    class page {
            
    public:
                mem_inline page( size_type _size, page 
    *old )
                
    {
                    size 
    = _size;
                    
    base = get_base();
                    next 
    = old;
                    prev 
    = NULL;
                    
    if( next )
                        next
    ->prev = this;
                    num_nodes 
    = 0;
                }


                mem_inline 
    ~page()
                
    {
                    node    
    *= head.next;

                    
    while( p )
                    
    {
                        head.next 
    = p->next;

                        p
    ->g_detach();
                        p
    ->~node();
                        node_pool.dealloc( p, 
    sizeof(node) );

                        p 
    = head.next;
                    }

                }


                mem_inline 
    void recycle( page *old )
                
    {
                    node    
    *= head.next;

                    
    while( p )
                    
    {
                        head.next 
    = p->next;

                        p
    ->g_detach();
                        p
    ->~node();
                        node_pool.dealloc( p, 
    sizeof(node) );
                        
                        p 
    = head.next;
                    }


                    head.next 
    = NULL;

                    size 
    = get_size();
                    
    base = get_base();
                    next 
    = old;
                    prev 
    = NULL;
                    
    if( next )
                        next
    ->prev = this;
                    num_nodes 
    = 0;
                }


                mem_inline 
    byte *get_base()
                
    {
                    
    return (byte *this + sizeof(page);
                }


                mem_inline size_type get_size()
                
    {
                    
    return static_cast<size_type>base - get_base() + size );
                }


                mem_inline size_type available() 
    const
                
    {
                    
    return size;
                }


                mem_inline 
    void *alloc( size_type req_size )
                
    {
                    
    void    *ptr = (void *base;

                    
    base += req_size;
                    size 
    -= req_size;
                
                    
    return ptr;
                }


                mem_inline time_type priority() 
    const
                
    {
                    time_type    last_use_time 
    = 0;

                    node    
    *= head.next;

                    
    while( p )
                    
    {
                        last_use_time 
    += p->get_last_use_time();

                        p 
    = p->next;
                    }


                    
    if( num_nodes != 0 )
                        last_use_time 
    /= static_cast<time_type>( num_nodes );

                    
    return last_use_time;
                }


                mem_inline 
    bool is_locked() const
                
    {
                    node    
    *= head.next;

                    
    while( p )
                    
    {
                        
    if( p->is_locked() )
                            
    return true;

                        p 
    = p->next;
                    }


                    
    return false;
                }


                mem_inline 
    bool operator < ( const page & right ) const
                
    {
                    
    return ( priority() < right.priority() );
                }


            
    public:
                mem_align union 
    {
                    
    struct {
                        
    byte                    *base;
                        page                    
    *next;
                        page                    
    *prev;
                        size_type                size;
                        node                    head;
                        size_type                num_nodes;
                    }
    ;
                    
    byte    pad[mem_page_pad];
                }
    ;
            }
    ;
            
            
    class chunk {
            
    public:
                mem_inline chunk( size_type _size, chunk 
    *old )
                
    {
                    size 
    = _size;
                    next 
    = old;
                    prev 
    = NULL;
                    
    if( next )
                        next
    ->prev = this;
                }


                mem_inline size_type available() 
    const
                
    {
                    
    return size;
                }


            
    public:
                chunk                    
    *next;
                chunk                    
    *prev;
                size_type                size;
            }
    ;

        
    public:
            mem_inline cache()
            
    {
                current_time 
    = 0;
                pages 
    = NULL;
                chunks 
    = NULL;
                allocated 
    = 0;
                g_num_nodes 
    = 0;
                num_recycle 
    = 0;
                num_chunk_alloc 
    = 0;
                num_pages 
    = 0;
                num_chunks 
    = 0;
                num_stream_alloc 
    = 0;
                num_page_del 
    = 0;
            }


            mem_inline 
    ~cache()
            
    {
                destory();
            }


            mem_inline time_type get_current_time()
            
    {
                
    return ( ++ current_time );
            }


            mem_inline 
    void *alloc( size_type size, entry *obj )
            
    {
                
    void    *ptr = NULL;

                
    ++ allocated;

                obj
    ->node_ptr = NULL;

                
    if( search_chunk( ptr, size ) )
                    
    return ptr;
                
    else if( search_page( ptr, size, obj ) )
                    
    return ptr;
                
    else if( (size + sizeof(page)) > al.available() )
                
    {
                    
    if( search_entry( ptr, size, obj ) )
                        
    return ptr;
                    
    else
                    
    {
                        
    if( recycle_page( size ) )
                        
    {
                            
    if( search_page( ptr, size, obj ) )
                                
    return ptr;
                            
    else
                            
    {
                                std::cout 
    << "fatal: failed to allocate memory!" << std::endl;
                                
    return NULL;
                            }

                        }

                        
    else
                        
    {
                            free_page( size );
                            allocate_page( size );

                            
    if( search_page( ptr, size, obj ) )
                                
    return ptr;
                            
    else
                            
    {
                                std::cout 
    << "fatal: failed to allocate memory!" << std::endl;
                                
    return NULL;
                            }

                        }

                    }

                }

                
    else
                
    {
                    allocate_page( size );

                    
    if( search_page( ptr, size, obj ) )
                        
    return ptr;
                    
    else
                    
    {
                        std::cout 
    << "fatal: failed to allocate memory!" << std::endl;
                        
    return NULL;
                    }

                }

            }


            mem_inline 
    void dealloc( void *ptr, size_type size, entry *obj )
            
    {
                
    -- allocated;

                
    if( obj->node_ptr )
                
    {
                    obj
    ->node_ptr->detach();
                    obj
    ->node_ptr->g_detach();
                    obj
    ->node_ptr->~node();
                    node_pool.dealloc( obj
    ->node_ptr, sizeof(node) );
                    obj
    ->node_ptr = NULL;

                    
    -- g_num_nodes;
                }


                
    if( size >= sizeof(chunk) )
                
    {
                    chunks 
    = new (ptr) chunk( size, chunks );

                    
    ++ num_chunks;
                }

            
                
    if( allocated == 0 )
                    destory();
            }


            mem_inline 
    void print()
            
    {
                std::cout 
    << std::endl;
                std::cout 
    << "========== cache Statistics ==========" << std::endl;
                std::cout 
    << std::endl;

                std::cout 
    << "current time: " << current_time << std::endl;
                std::cout 
    << "number of allocations: " << allocated << std::endl;
                std::cout 
    << "number of chunks: " << num_chunks << std::endl;
                std::cout 
    << "number of chunk allocations: " << num_chunk_alloc << std::endl;
                std::cout 
    << "number of nodes: " << g_num_nodes << std::endl;
                std::cout 
    << "number of stream allocations: " << num_stream_alloc << std::endl;
                std::cout 
    << "number of pages: " << num_pages << std::endl;
                std::cout 
    << "number of page recycles: " << num_recycle << std::endl;
                std::cout 
    << "number of page deletions: " << num_page_del << std::endl;

                std::cout 
    << std::endl;
                std::cout 
    << "======================================" << std::endl;
                std::cout 
    << std::endl;
            }


        
    private:
            mem_inline 
    void destory()
            
    {
                page    
    *= pages;
            
                
    while( p )
                
    {
                    pages 
    = p->next;
                    p
    ->~page();
                    al.dealloc( p, p
    ->get_size() );
                    p 
    = pages;
                }


                chunks 
    = NULL;

                g_num_nodes 
    = 0;
                num_recycle 
    = 0;
                num_chunk_alloc 
    = 0;
                num_pages 
    = 0;
                num_chunks 
    = 0;
                num_stream_alloc 
    = 0;
                num_page_del 
    = 0;
            }


            mem_inline 
    bool search_chunk( void * & ptr, size_type size )
            
    {
                chunk    
    *= chunks;
                
                
    while( p )
                
    {
                    
    if( size <= p->available() )
                    
    {
                        ptr 
    = (void *) p;
                        
                        
    if( p->prev )
                            p
    ->prev->next = p->next;
                        
    if( p->next )
                            p
    ->next->prev = p->prev;

                        
    ++ num_chunk_alloc;
                        
    -- num_chunks;
                        
                        
    return true;
                    }


                    p 
    = p->next;
                }


                
    return false;
            }


            mem_inline 
    bool search_page( void * & ptr, size_type size, entry *obj )
            
    {
                page    
    *= pages;
                
                
    while( p )
                
    {
                    
    if( size <= p->available() )
                    
    {
                        ptr 
    = p->alloc( size );

                        
    new (node_pool.alloc( sizeof(node) )) node( obj, p->head.next, g_head.g_next, &p->head, &g_head );
                        
    ++ p->num_nodes;
                        
    ++ g_num_nodes;
                        
                        
    return true;
                    }


                    p 
    = p->next;
                }


                
    return false;
            }


            mem_inline 
    bool search_entry( void * & ptr, size_type size, entry *obj )
            
    {
                node    
    *old = NULL;
                node    
    *= g_head.g_next;

                
    while( p )
                
    {
                    
    if!p->is_locked() &&
                        p
    ->stream_size() >= size )
                    
    {
                        
    if( old )
                        
    {
                            
    if*p->ptr < *old->ptr )
                                old 
    = p;
                        }

                        
    else
                            old 
    = p;
                    }


                    p 
    = p->g_next;
                }


                
    if( old && old->stream_out( ptr ) )
                
    {
                    old
    ->ptr = obj;

                    obj
    ->node_ptr = old;

                    
    ++ num_stream_alloc;
                        
                    
    return true;
                }


                
    return false;
            }


            mem_inline 
    bool recycle_page( size_type size )
            
    {
                
    if( pages )
                
    {
                    page    
    *old = NULL;
                    page    
    *= pages;

                    
    while( p )
                    
    {
                        
    if!p->is_locked() &&
                            p
    ->get_size() >= size )
                        
    {
                            
    if( old )
                            
    {
                                
    if*< *old )
                                    old 
    = p;
                            }

                            
    else
                                old 
    = p;
                        }


                        p 
    = p->next;
                    }


                    
    if( old )
                    
    {
                        
    if( old != pages )
                        
    {
                            
    if( old->prev )
                                old
    ->prev->next = old->next;
                            
    if( old->next )
                                old
    ->next->prev = old->prev;

                            old
    ->recycle( pages );
                            pages 
    = old;
                        }

                        
    else
                        
    {
                            old
    ->recycle( old->next );
                        }


                        
    ++ num_recycle;

                        
    return true;
                    }

                }


                
    return false;
            }


            mem_inline 
    bool delete_page( size_type & del_size )
            
    {
                
    if( pages )
                
    {
                    page    
    *old = NULL;
                    page    
    *= pages;

                    
    while( p )
                    
    {
                        
    if!p->is_locked() )
                        
    {
                            
    if( old )
                            
    {
                                
    if*< *old )
                                    old 
    = p;
                            }

                            
    else
                                old 
    = p;
                        }


                        p 
    = p->next;
                    }


                    
    if( old )
                    
    {
                        
    if( old != pages )
                        
    {
                            
    if( old->prev )
                                old
    ->prev->next = old->next;
                            
    if( old->next )
                                old
    ->next->prev = old->prev;
                        }

                        
    else
                        
    {
                            pages 
    = old->next;
                            
    if( pages )
                                pages
    ->prev = NULL;
                        }


                        del_size 
    = old->get_size();

                        old
    ->~page();
                        al.dealloc( old, old
    ->get_size() );

                        
    -- num_pages;
                        
    ++ num_page_del;

                        
    return true;
                    }

                }


                del_size 
    = 0;
                
                
    return false;
            }


            mem_inline 
    void free_page( size_type size )
            
    {
                size_type    del_size 
    = 0;
                size_type    freed_size 
    = 0;

                
    while( freed_size < size && delete_page( del_size ) )
                
    {
                    freed_size 
    += del_size;
                }

            }


            mem_inline 
    void allocate_page( size_type size )
            
    {
                size_type    asize 
    = mem_min( mem_max( sizeof(page) + size, mem_page_size ), al.available() );

                pages 
    = new (al.alloc( asize )) page( asize - sizeof(page), pages );

                
    ++ num_pages;
            }


        
    private:
            time_type                        current_time;
            time_type                        allocated;
            ALLOC                            al;
            node                            g_head;
            size_type                        g_num_nodes;
            page                            
    *pages;
            size_type                        num_pages;
            size_type                        num_recycle;
            chunk                            
    *chunks;
            size_type                        num_chunks;
            size_type                        num_chunk_alloc;
            size_type                        num_stream_alloc;
            size_type                        num_page_del;

        
    public:
            
    static pool< ALLOC >            node_pool;
        }
    ;

        
    class man {
        
    public:
            mem_inline man()
            
    {
                m_heap 
    = NULL;

                upl 
    = NULL;
                apl 
    = NULL;

                num_stream_out 
    = 0;
            }


            mem_inline 
    ~man()
            
    {
                
    if( apl )
                    delete apl;
                
    if( upl )
                    delete upl;

                
    if( m_heap )
                    delete m_heap;
            }


            mem_inline 
    void begin( size_type heap_size )
            
    {
                m_heap 
    = new heap( heap_size );

                upl 
    = new pool< allocator >;
                apl 
    = new pool< aligned_allocator >;

                num_stream_out 
    = 0;
            }


            mem_inline 
    void end()
            
    {
                delete apl;
                apl 
    = NULL;
                delete upl;
                upl 
    = NULL;

                delete m_heap;
                m_heap 
    = NULL;
            }


            mem_inline 
    void *alloc( size_type size )
            
    {
                
    return upl->alloc( size );
            }


            mem_inline 
    void dealloc( void *ptr, size_type size )
            
    {
                
    return upl->dealloc( ptr, size );
            }


            mem_inline 
    void *aligned_alloc( size_type size )
            
    {
                
    return apl->alloc( size );
            }


            mem_inline 
    void aligned_dealloc( void *ptr, size_type size )
            
    {
                
    return apl->dealloc( ptr, size );
            }


            mem_inline 
    void print()
            
    {
                std::cout 
    << std::endl;
                std::cout 
    << "********** MemMan Statistics **********" << std::endl;
                std::cout 
    << std::endl;

                
    if( m_heap )
                
    {
                    std::cout 
    << "global heap: " << std::endl;
                    m_heap
    ->print();
                }


                std::cout 
    << std::endl;
                std::cout 
    << "page size: " << mem_page_size << " Byte" << std::endl;
                std::cout 
    << std::endl;

                
    if( upl )
                
    {
                    std::cout 
    << "unaligned pool: " << std::endl;
                    upl
    ->print();
                }


                
    if( apl )
                
    {
                    std::cout 
    << "aligned pool: " << std::endl;
                    apl
    ->print();
                }


                std::cout 
    << "unaligned node pool: " << std::endl;
                cache
    < mem::man::allocator >::node_pool.print();

                std::cout 
    << "aligned node pool: " << std::endl;
                cache
    < mem::man::aligned_allocator >::node_pool.print();

                std::cout 
    << "unaligned cache: " << std::endl;
                cache
    < mem::man::allocator >::entry::pl.print();

                std::cout 
    << "aligned cache: " << std::endl;
                cache
    < mem::man::aligned_allocator >::entry::pl.print();

                std::cout 
    << std::endl;
                std::cout 
    << "number of stream_out: " << num_stream_out << std::endl;
                std::cout 
    << std::endl;

                std::cout 
    << std::endl;
                std::cout 
    << "***************************************" << std::endl;
                std::cout 
    << std::endl;
            }


        
    public:
            
    static heap    *m_heap;

        
    public:
            
    class allocator {
            
    public:
                mem_inline 
    void *alloc( size_type size )
                
    {
                    
    return m_heap->alloc( size );
                }


                mem_inline 
    void dealloc( void *ptr, size_type size )
                
    {
                    m_heap
    ->dealloc( ptr, size );
                }


                mem_inline size_type available() 
    const
                
    {
                    
    return m_heap->available();
                }

            }
    ;

            
    class aligned_allocator {
            
    public:
                mem_inline 
    void *alloc( size_type size )
                
    {
                    
    return m_heap->aligned_alloc( size );
                }


                mem_inline 
    void dealloc( void *ptr, size_type size )
                
    {
                    m_heap
    ->aligned_dealloc( ptr, size );
                }


                mem_inline size_type available() 
    const
                
    {
                    
    return m_heap->available();
                }

            }
    ;

        
    public:
            pool
    < allocator >            *upl;
            pool
    < aligned_allocator >    *apl;
        }
    ;

        typedef cache
    < man::allocator >::entry            resource;
        typedef cache
    < man::aligned_allocator >::entry    aligned_resource;

    }
        //    namespace mem

    extern mem::man        memman;


    #pragma pack(pop)


    #endif    //    __MEMMAN__

    /**************************************************
     *
     * MemMan 3.0.0.0 beta
     *
     * Copyright (C) 2007 - 2008 by Len3d
     * All rights reserved.
     *
     ************************************************
    */


    #ifndef __MEMMAN_DEF__
    #define __MEMMAN_DEF__


    #include 
    "memman3.h"

    mem::man                                    memman;
    mem::heap                                    
    *mem::man::m_heap;
    mem::pool
    < mem::man::allocator >            mem::cache< mem::man::allocator >::node_pool;
    mem::pool
    < mem::man::aligned_allocator >    mem::cache< mem::man::aligned_allocator >::node_pool;
    mem::time_type                                mem::num_stream_out;
    mem::cache
    < mem::man::allocator >            mem::cache< mem::man::allocator >::entry::pl;
    mem::cache
    < mem::man::aligned_allocator >    mem::cache< mem::man::aligned_allocator >::entry::pl;


    #endif    //    __MEMMAN_DEF__
  • 相关阅读:
    hybrid项目h5页路由回退问题解决
    各个端类型判断
    图片展示方法总结
    微信小程序简易table组件实现
    微信小程序动画技巧
    git常用命令
    小程序跳转
    excel日期插件
    excel省市区三级分类级联
    mysql字符串分割操作
  • 原文地址:https://www.cnblogs.com/len3d/p/993088.html
Copyright © 2020-2023  润新知