예제 #1
0
void erts_factory_trim_and_close(ErtsHeapFactory* factory,
				 Eterm *brefs, Uint brefs_size)
{
    ErlHeapFragment *bp;

    switch (factory->mode) {
    case FACTORY_MESSAGE: {
	ErtsMessage *mp = factory->message;
	if (mp->data.attached == ERTS_MSG_COMBINED_HFRAG) {
	    if (!factory->heap_frags) {
		Uint sz = factory->hp - factory->hp_start;
		mp = erts_shrink_message(mp, sz, brefs, brefs_size);
		factory->message = mp;
		factory->mode = FACTORY_CLOSED;
		return;
	    }
	    /*else we don't trim multi fragmented messages for now (off_heap...) */
	    break;
	}
	/* Fall through... */
    }
    case FACTORY_HEAP_FRAGS:
	bp = factory->heap_frags;
	if (!bp)
	    break;
        if (bp->next == NULL) {
            Uint used_sz = factory->hp - bp->mem;
            ASSERT(used_sz <= bp->alloc_size);
	    if (used_sz > 0) {
                if (used_sz != bp->alloc_size)
                    bp = erts_resize_message_buffer(bp, used_sz,
                                                    brefs, brefs_size);
            }
	    else {
		free_message_buffer(bp);
		bp = NULL;
	    }
	    factory->heap_frags = bp;
	    if (factory->mode == FACTORY_MESSAGE)
		factory->message->data.heap_frag = bp;
            factory->mode = FACTORY_CLOSED;
            return;
        }
        /*else we don't trim multi fragmented messages for now (off_heap...) */
    default:
	break;
    }
    erts_factory_close(factory);
}
예제 #2
0
void erts_factory_trim_and_close(ErtsHeapFactory* factory,
				 Eterm *brefs, Uint brefs_size)
{
    if (factory->mode == FACTORY_HEAP_FRAGS) {
        ErlHeapFragment* bp = factory->heap_frags;
        if (bp->next == NULL) {
            Uint used_sz = factory->hp - bp->mem;
            ASSERT(used_sz <= bp->alloc_size);
            factory->heap_frags = erts_resize_message_buffer(bp, used_sz,
                                                             brefs, brefs_size);
            factory->mode = FACTORY_CLOSED;
            return;
        }
        /*else we don't trim multi fragmented messages for now */
    }
    erts_factory_close(factory);
}
예제 #3
0
Eterm
erts_msg_distext2heap(Process *pp,
                      ErtsProcLocks *plcksp,
                      ErlHeapFragment **bpp,
                      Eterm *tokenp,
                      ErtsDistExternal *dist_extp)
{
    Eterm msg;
    Uint tok_sz = 0;
    Eterm *hp = NULL;
    Eterm *hp_end = NULL;
    ErlOffHeap *ohp;
    Sint sz;

    *bpp = NULL;
    sz = erts_decode_dist_ext_size(dist_extp);
    if (sz < 0)
        goto decode_error;
    if (is_not_nil(*tokenp)) {
        ErlHeapFragment *heap_frag = erts_dist_ext_trailer(dist_extp);
        tok_sz = heap_frag->used_size;
        sz += tok_sz;
    }
    if (pp)
        hp = erts_alloc_message_heap(sz, bpp, &ohp, pp, plcksp);
    else {
        *bpp = new_message_buffer(sz);
        hp = (*bpp)->mem;
        ohp = &(*bpp)->off_heap;
    }
    hp_end = hp + sz;
    msg = erts_decode_dist_ext(&hp, ohp, dist_extp);
    if (is_non_value(msg))
        goto decode_error;
    if (is_not_nil(*tokenp)) {
        ErlHeapFragment *heap_frag = erts_dist_ext_trailer(dist_extp);
        *tokenp = copy_struct(*tokenp, tok_sz, &hp, ohp);
        erts_cleanup_offheap(&heap_frag->off_heap);
    }
    erts_free_dist_ext_copy(dist_extp);
    if (hp_end != hp) {
        if (!(*bpp)) {
            HRelease(pp, hp_end, hp);
        }
        else {
            Uint final_size = hp - &(*bpp)->mem[0];
            Eterm brefs[2] = {msg, *tokenp};
            ASSERT(sz - (hp_end - hp) == final_size);
            *bpp = erts_resize_message_buffer(*bpp, final_size, &brefs[0], 2);
            msg = brefs[0];
            *tokenp = brefs[1];
        }
    }
    return msg;

decode_error:
    if (is_not_nil(*tokenp)) {
        ErlHeapFragment *heap_frag = erts_dist_ext_trailer(dist_extp);
        erts_cleanup_offheap(&heap_frag->off_heap);
    }
    erts_free_dist_ext_copy(dist_extp);
    if (*bpp) {
        free_message_buffer(*bpp);
        *bpp = NULL;
    }
    else if (hp) {
        HRelease(pp, hp_end, hp);
    }
    return THE_NON_VALUE;
}