Exemplo n.º 1
0
static  void *worker (void *p)
{
	register int i;

	for (i = 0; i < PERINC; i++) {
		EnterSpinLock (&lock);
		EnterSpinLock (&lock);
		val++;
		LeaveSpinLock (&lock);
		LeaveSpinLock (&lock);
	}

	InterlockedIncrement (&done_threads);
	return NULL;
}//end: worker()
Exemplo n.º 2
0
void mempool_node_put(mempool p, void *data)
{
    struct node *node;

    node = DATA_TO_NODE(data);
#ifdef MEMPOOLASSERT
    if(node->magic != NODE_MAGIC) {
        ShowError(read_message("Source.common.mempool_node_put"), p->name,  data);
        return; // lost,
    }

    {
        struct pool_segment *node_seg = node->segment;
        if(node_seg->pool != p) {
            ShowError(read_message("Source.common.mempool_node_put2"), p->name, data, node_seg->pool);
            return;
        }
    }

    // reset used flag.
    node->used = false;
#endif

    //
    EnterSpinLock(&p->nodeLock);
    node->next = p->free_list;
    p->free_list = node;
    LeaveSpinLock(&p->nodeLock);

    InterlockedIncrement64(&p->num_nodes_free);

}//end: mempool_node_put()
Exemplo n.º 3
0
static void *mempool_async_allocator(void *x)
{
    mempool p;


    while(1) {
        if(l_async_terminate > 0)
            break;

        EnterSpinLock(&l_mempoolListLock);

        for(p = l_mempoolList;  p != NULL;  p = p->next) {

            if(p->num_nodes_free < p->elem_realloc_thresh) {
                // add new segment.
                segment_allocate_add(p, p->elem_realloc_step);
                // increase stats counter
                InterlockedIncrement64(&p->num_realloc_events);
            }

        }

        LeaveSpinLock(&l_mempoolListLock);

        ramutex_lock(l_async_lock);
        racond_wait(l_async_cond,   l_async_lock,  -1);
        ramutex_unlock(l_async_lock);
    }


    return NULL;
}//end: mempool_async_allocator()
Exemplo n.º 4
0
//-------------------------------------------------------------------------
MH_STATUS WINAPI MH_Initialize(VOID)
{
    MH_STATUS status = MH_OK;

    EnterSpinLock();

    if (g_hHeap == NULL)
    {
        g_hHeap = HeapCreate(0, 0, 0);
        if (g_hHeap != NULL)
        {
            // Initialize the internal function buffer.
            InitializeBuffer();
        }
        else
        {
            status = MH_ERROR_MEMORY_ALLOC;
        }
    }
    else
    {
        status = MH_ERROR_ALREADY_INITIALIZED;
    }

    LeaveSpinLock();

    return status;
}
Exemplo n.º 5
0
void mempool_node_put(mempool p, void *data){
	struct node *node;
	
	node = DATA_TO_NODE(data);
#ifdef MEMPOOLASSERT
	if(node->magic != NODE_MAGIC){
		ShowError("Mempool [%s] node_put failed, given address (%p) has invalid magic.\n", p->name,  data);
		return; // lost, 
	}

	{
		struct pool_segment *node_seg = node->segment;
		if(node_seg->pool != p){
			ShowError("Mempool [%s] node_put faild, given node (data address %p) doesnt belongs to this pool. ( Node Origin is [%s] )\n", p->name, data, node_seg->pool);
			return;
		}
	}
	
	// reset used flag.
	node->used = false;
#endif

	// 
	EnterSpinLock(&p->nodeLock);
		node->next = p->free_list;
		p->free_list = node;
	LeaveSpinLock(&p->nodeLock);
	
	InterlockedIncrement64(&p->num_nodes_free);

}//end: mempool_node_put()
Exemplo n.º 6
0
//-------------------------------------------------------------------------
MH_STATUS WINAPI MH_ApplyQueued(VOID)
{
    MH_STATUS status = MH_OK;
    UINT i, first = INVALID_HOOK_POS;

    EnterSpinLock();

    if (g_hHeap != NULL)
    {
        for (i = 0; i < g_hooks.size; ++i)
        {
            if (g_hooks.pItems[i].isEnabled != g_hooks.pItems[i].queueEnable)
            {
                first = i;
                break;
            }
        }

        if (first != INVALID_HOOK_POS)
        {
            FROZEN_THREADS threads;
            Freeze(&threads, ALL_HOOKS_POS, ACTION_APPLY_QUEUED);

            for (i = first; i < g_hooks.size; ++i)
            {
                PHOOK_ENTRY pHook = &g_hooks.pItems[i];
                if (pHook->isEnabled != pHook->queueEnable)
                {
                    status = EnableHookLL(i, pHook->queueEnable);
                    if (status != MH_OK)
                        break;
                }
            }

            Unfreeze(&threads);
        }
    }
    else
    {
        status = MH_ERROR_NOT_INITIALIZED;
    }

    LeaveSpinLock();

    return status;
}
Exemplo n.º 7
0
//-------------------------------------------------------------------------
static MH_STATUS EnableHook(LPVOID pTarget, BOOL enable)
{
    MH_STATUS status = MH_OK;

    EnterSpinLock();

    if (g_hHeap != NULL)
    {
        if (pTarget == MH_ALL_HOOKS)
        {
            status = EnableAllHooksLL(enable);
        }
        else
        {
            FROZEN_THREADS threads;
            UINT pos = FindHookEntry(pTarget);
            if (pos != INVALID_HOOK_POS)
            {
                if (g_hooks.pItems[pos].isEnabled != enable)
                {
                    Freeze(&threads, pos, ACTION_ENABLE);

                    status = EnableHookLL(pos, enable);

                    Unfreeze(&threads);
                }
                else
                {
                    status = enable ? MH_ERROR_ENABLED : MH_ERROR_DISABLED;
                }
            }
            else
            {
                status = MH_ERROR_NOT_CREATED;
            }
        }
    }
    else
    {
        status = MH_ERROR_NOT_INITIALIZED;
    }

    LeaveSpinLock();

    return status;
}
Exemplo n.º 8
0
//-------------------------------------------------------------------------
MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget)
{
    MH_STATUS status = MH_OK;

    EnterSpinLock();

    if (g_hHeap != NULL)
    {
        UINT pos = FindHookEntry(pTarget);
        if (pos != INVALID_HOOK_POS)
        {
            if (g_hooks.pItems[pos].isEnabled)
            {
                FROZEN_THREADS threads;
                Freeze(&threads, pos, ACTION_DISABLE);

                status = EnableHookLL(pos, FALSE);

                Unfreeze(&threads);
            }

            if (status == MH_OK)
            {
                FreeBuffer(g_hooks.pItems[pos].pTrampoline);
                DeleteHookEntry(pos);
            }
        }
        else
        {
            status = MH_ERROR_NOT_CREATED;
        }
    }
    else
    {
        status = MH_ERROR_NOT_INITIALIZED;
    }

    LeaveSpinLock();

    return status;
}
Exemplo n.º 9
0
void *mempool_node_get(mempool p)
{
    struct node *node;
    int64 num_used;

    if(p->num_nodes_free < p->elem_realloc_thresh)
        racond_signal(l_async_cond);

    while(1) {

        EnterSpinLock(&p->nodeLock);

        node = p->free_list;
        if(node != NULL)
            p->free_list = node->next;

        LeaveSpinLock(&p->nodeLock);

        if(node != NULL)
            break;

        rathread_yield();
    }

    InterlockedDecrement64(&p->num_nodes_free);

    // Update peak value
    num_used = (p->num_nodes_total - p->num_nodes_free);
    if(num_used > p->peak_nodes_used) {
        InterlockedExchange64(&p->peak_nodes_used, num_used);
    }

#ifdef MEMPOOLASSERT
    node->used = true;
#endif

    return NODE_TO_DATA(node);
}//end: mempool_node_get()
Exemplo n.º 10
0
void mempool_final()
{
    mempool p, pn;

    if(rand()%2 + 1)
        return;

    ShowStatus("Mempool: Terminating async. allocation worker and remaining pools.\n");

    // Terminate worker / wait until its terminated.
    InterlockedIncrement(&l_async_terminate);
    racond_signal(l_async_cond);
    rathread_wait(l_async_thread, NULL);

    // Destroy cond var and mutex.
    racond_destroy(l_async_cond);
    ramutex_destroy(l_async_lock);

    // Free remaining mempools
    // ((bugged code! this should halppen, every mempool should
    //      be freed by the subsystem that has allocated it.)
    //
    EnterSpinLock(&l_mempoolListLock);
    p = l_mempoolList;
    while(1) {
        if(p == NULL)
            break;

        pn = p->next;

        ShowWarning(read_message("Source.common.mempool_final"), p->name);
        mempool_destroy(p);

        p = pn;
    }
    LeaveSpinLock(&l_mempoolListLock);

}//end: mempool_final()
Exemplo n.º 11
0
//-------------------------------------------------------------------------
MH_STATUS WINAPI MH_Uninitialize(VOID)
{
    MH_STATUS status = MH_OK;

    EnterSpinLock();

    if (g_hHeap != NULL)
    {
        status = EnableAllHooksLL(FALSE);
        if (status == MH_OK)
        {
            // Free the internal function buffer.

            // HeapFree is actually not required, but some tools detect a false
            // memory leak without HeapFree.

            UninitializeBuffer();

            HeapFree(g_hHeap, 0, g_hooks.pItems);
            HeapDestroy(g_hHeap);

            g_hHeap = NULL;

            g_hooks.pItems   = NULL;
            g_hooks.capacity = 0;
            g_hooks.size     = 0;
        }
    }
    else
    {
        status = MH_ERROR_NOT_INITIALIZED;
    }

    LeaveSpinLock();

    return status;
}
Exemplo n.º 12
0
//-------------------------------------------------------------------------
static MH_STATUS QueueHook(LPVOID pTarget, BOOL queueEnable)
{
    MH_STATUS status = MH_OK;

    EnterSpinLock();

    if (g_hHeap != NULL)
    {
        if (pTarget == MH_ALL_HOOKS)
        {
            UINT i;
            for (i = 0; i < g_hooks.size; ++i)
                g_hooks.pItems[i].queueEnable = queueEnable;
        }
        else
        {
            UINT pos = FindHookEntry(pTarget);
            if (pos != INVALID_HOOK_POS)
            {
                g_hooks.pItems[pos].queueEnable = queueEnable;
            }
            else
            {
                status = MH_ERROR_NOT_CREATED;
            }
        }
    }
    else
    {
        status = MH_ERROR_NOT_INITIALIZED;
    }

    LeaveSpinLock();

    return status;
}
Exemplo n.º 13
0
void mempool_destroy(mempool p)
{
    struct  pool_segment *seg, *segnext;
    struct  node *niter;
    mempool piter, pprev;
    char *ptr;
    int64 i;

#ifdef MEMPOOL_DEBUG
    ShowDebug(read_message("Source.common.mempool_debug4"), p->name);
#endif

    // Unlink from global list.
    EnterSpinLock(&l_mempoolListLock);
    piter = l_mempoolList;
    pprev = l_mempoolList;
    while(1) {
        if(piter == NULL)
            break;


        if(piter == p) {
            // unlink from list,
            //
            if(pprev == l_mempoolList) {
                // this (p) is list begin. so set next as head.
                l_mempoolList = p->next;
            } else {
                // replace prevs next wuth our next.
                pprev->next = p->next;
            }
            break;
        }

        pprev = piter;
        piter = piter->next;
    }

    p->next = NULL;
    LeaveSpinLock(&l_mempoolListLock);


    // Get both locks.
    EnterSpinLock(&p->segmentLock);
    EnterSpinLock(&p->nodeLock);


    if(p->num_nodes_free != p->num_nodes_total)
        ShowWarning(read_message("Source.common.mempool_destroy"), p->name, (p->num_nodes_total - p->num_nodes_free));

    // Free All Segments (this will also free all nodes)
    // The segment pointer is the base pointer to the whole segment.
    seg = p->segments;
    while(1) {
        if(seg == NULL)
            break;

        segnext = seg->next;

        // ..
        if(p->ondealloc != NULL) {
            // walk over the segment, and call dealloc callback!
            ptr = (char *)seg;
            ptr += ALIGN_TO_16(sizeof(struct pool_segment));
            for(i = 0; i < seg->num_nodes_total; i++) {
                niter = (struct node *)ptr;
                ptr += sizeof(struct node);
                ptr += p->elem_size;
#ifdef MEMPOOLASSERT
                if(niter->magic != NODE_MAGIC) {
                    ShowError(read_message("Source.common.mempool_destroy2"), p->name, niter);
                    continue;
                }
#endif

                p->ondealloc(NODE_TO_DATA(niter));


            }
        }//endif: ondealloc callback?

        // simple ..
        aFree(seg);

        seg = segnext;
    }

    // Clear node ptr
    p->free_list = NULL;
    InterlockedExchange64(&p->num_nodes_free, 0);
    InterlockedExchange64(&p->num_nodes_total, 0);
    InterlockedExchange64(&p->num_segments, 0);
    InterlockedExchange64(&p->num_bytes_total, 0);

    LeaveSpinLock(&p->nodeLock);
    LeaveSpinLock(&p->segmentLock);

    // Free pool itself :D
    aFree(p->name);
    aFree(p);

}//end: mempool_destroy()
Exemplo n.º 14
0
mempool mempool_create(const char *name,
                       uint64 elem_size,
                       uint64 initial_count,
                       uint64 realloc_count,
                       memPoolOnNodeAllocationProc onNodeAlloc,
                       memPoolOnNodeDeallocationProc onNodeDealloc)
{
    //..
    uint64 realloc_thresh;
    mempool pool;
    pool = (mempool)aCalloc(1,  sizeof(struct mempool));

    if(pool == NULL) {
        ShowFatalError(read_message("Source.common.mempool_create"), sizeof(struct mempool));
        exit(EXIT_FAILURE);
    }

    // Check minimum initial count / realloc count requirements.
    if(initial_count < 50)
        initial_count = 50;
    if(realloc_count < 50)
        realloc_count = 50;

    // Set Reallocation threshold to 5% of realloc_count, at least 10.
    realloc_thresh = (realloc_count/100)*5; //
    if(realloc_thresh < 10)
        realloc_thresh = 10;

    // Initialize members..
    pool->name = aStrdup(name);
    pool->elem_size = ALIGN_TO_16(elem_size);
    pool->elem_realloc_step = realloc_count;
    pool->elem_realloc_thresh = realloc_thresh;
    pool->onalloc = onNodeAlloc;
    pool->ondealloc = onNodeDealloc;

    InitializeSpinLock(&pool->segmentLock);
    InitializeSpinLock(&pool->nodeLock);

    // Initial Statistic values:
    pool->num_nodes_total = 0;
    pool->num_nodes_free = 0;
    pool->num_segments = 0;
    pool->num_bytes_total = 0;
    pool->peak_nodes_used = 0;
    pool->num_realloc_events = 0;

    //
#ifdef MEMPOOL_DEBUG
    ShowDebug(read_message("Source.common.mempool_create"), pool->name,  pool->elem_size,  initial_count,  pool->elem_realloc_step);
#endif

    // Allocate first segment directly :)
    segment_allocate_add(pool, initial_count);


    // Add Pool to the global pool list
    EnterSpinLock(&l_mempoolListLock);
    pool->next = l_mempoolList;
    l_mempoolList = pool;
    LeaveSpinLock(&l_mempoolListLock);


    return pool;
}//end: mempool_create()
Exemplo n.º 15
0
static void segment_allocate_add(mempool p,  uint64 count)
{

    // Required Memory:
    //  sz( segment )
    //  count * sz( real_node_size )
    //
    //  where real node size is:
    //      ALIGN_TO_16( sz( node ) ) + p->elem_size
    //  so the nodes usable address is  nodebase + ALIGN_TO_16(sz(node))
    //
    size_t total_sz;
    struct pool_segment *seg = NULL;
    struct node *nodeList = NULL;
    struct node *node = NULL;
    char *ptr = NULL;
    uint64 i;

    total_sz = ALIGN_TO_16(sizeof(struct pool_segment))
               + ((size_t)count * (sizeof(struct node) + (size_t)p->elem_size)) ;

#ifdef MEMPOOL_DEBUG
    ShowDebug(read_message("Source.common.mempool_debug"), p->name, count, (float)total_sz/1024.f/1024.f);
#endif

    // allocate! (spin forever until weve got the memory.)
    i=0;
    while(1) {
        ptr = (char *)aMalloc(total_sz);
        if(ptr != NULL) break;

        i++; // increase failcount.
        if(!(i & 7)) {
            ShowWarning(read_message("Source.common.mempool_debug2"), (float)total_sz/1024.f/1024.f,  i);
#ifdef WIN32
            Sleep(1000);
#else
            sleep(1);
#endif
        } else {
            rathread_yield(); /// allow/force vuln. ctxswitch
        }
    }//endwhile: allocation spinloop.

    // Clear Memory.
    memset(ptr, 0x00, total_sz);

    // Initialize segment struct.
    seg = (struct pool_segment *)ptr;
    ptr += ALIGN_TO_16(sizeof(struct pool_segment));

    seg->pool = p;
    seg->num_nodes_total = count;
    seg->num_bytes = total_sz;


    // Initialze nodes!
    nodeList = NULL;
    for(i = 0; i < count; i++) {
        node = (struct node *)ptr;
        ptr += sizeof(struct node);
        ptr += p->elem_size;

        node->segment = seg;
#ifdef MEMPOOLASSERT
        node->used = false;
        node->magic = NODE_MAGIC;
#endif

        if(p->onalloc != NULL)  p->onalloc(NODE_TO_DATA(node));

        node->next = nodeList;
        nodeList = node;
    }



    // Link in Segment.
    EnterSpinLock(&p->segmentLock);
    seg->next = p->segments;
    p->segments = seg;
    LeaveSpinLock(&p->segmentLock);

    // Link in Nodes
    EnterSpinLock(&p->nodeLock);
    nodeList->next = p->free_list;
    p->free_list = nodeList;
    LeaveSpinLock(&p->nodeLock);


    // Increase Stats:
    InterlockedExchangeAdd64(&p->num_nodes_total,  count);
    InterlockedExchangeAdd64(&p->num_nodes_free,   count);
    InterlockedIncrement64(&p->num_segments);
    InterlockedExchangeAdd64(&p->num_bytes_total,   total_sz);

}//end: segment_allocate_add()
Exemplo n.º 16
0
//-------------------------------------------------------------------------
MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal)
{
    MH_STATUS status = MH_OK;

    EnterSpinLock();

    if (g_hHeap != NULL)
    {
        if ((g_Flags & MH_FLAGS_SKIP_EXEC_CHECK)
            || (IsExecutableAddress(pTarget) && IsExecutableAddress(pDetour))
            )
        {
            UINT pos = FindHookEntry(pTarget);
            if (pos == INVALID_HOOK_POS)
            {
                LPVOID pBuffer = AllocateBuffer(pTarget);
                if (pBuffer != NULL)
                {
                    TRAMPOLINE ct;

                    ct.pTarget = pTarget;
                    ct.pDetour = pDetour;
                    ct.pTrampoline = pBuffer;
                    if (CreateTrampolineFunction(&ct))
                    {
                        PHOOK_ENTRY pHook = AddHookEntry();
                        if (pHook != NULL)
                        {
                            pHook->pTarget     = ct.pTarget;
#ifdef _M_X64
                            pHook->pDetour     = ct.pRelay;
#else
                            pHook->pDetour     = ct.pDetour;
#endif
                            pHook->pTrampoline = ct.pTrampoline;
                            pHook->patchAbove  = ct.patchAbove;
                            pHook->isEnabled   = FALSE;
                            pHook->queueEnable = FALSE;
                            pHook->nIP         = ct.nIP;
                            memcpy(pHook->oldIPs, ct.oldIPs, ARRAYSIZE(ct.oldIPs));
                            memcpy(pHook->newIPs, ct.newIPs, ARRAYSIZE(ct.newIPs));

                            // Back up the target function.

                            if (ct.patchAbove)
                            {
                                memcpy(
                                    pHook->backup,
                                    (LPBYTE)pTarget - sizeof(JMP_REL),
                                    sizeof(JMP_REL) + sizeof(JMP_REL_SHORT));
                            }
                            else
                            {
                                memcpy(pHook->backup, pTarget, sizeof(JMP_REL));
                            }

                            if (ppOriginal != NULL)
                                *ppOriginal = pHook->pTrampoline;
                        }
                        else
                        {
                            status = MH_ERROR_MEMORY_ALLOC;
                        }
                    }
                    else
                    {
                        status = MH_ERROR_UNSUPPORTED_FUNCTION;
                    }

                    if (status != MH_OK)
                    {
                        FreeBuffer(pBuffer);
                    }
                }
                else
                {
                    status = MH_ERROR_MEMORY_ALLOC;
                }
            }
            else
            {
                status = MH_ERROR_ALREADY_CREATED;
            }
        }
        else
        {
            status = MH_ERROR_NOT_EXECUTABLE;
        }
    }
    else
    {
        status = MH_ERROR_NOT_INITIALIZED;
    }

    LeaveSpinLock();

    return status;
}