UWord erts_alc_test()

in erts/emulator/beam/erl_alloc.c [3518:3737]


UWord erts_alc_test(UWord op, UWord a1, UWord a2, UWord a3)
{
    switch (op >> 8) {
    case 0x0:	return erts_alcu_test(op,  a1, a2);
    case 0x1:	return erts_gfalc_test(op, a1, a2);
    case 0x2:	return erts_bfalc_test(op, a1, a2);
    case 0x3:	return erts_afalc_test(op, a1, a2);
    case 0x4:	return erts_mseg_test(op,  a1, a2, a3);
    case 0x5:	return erts_aoffalc_test(op, a1, a2);
    case 0xf:
	switch (op) {
	case 0xf00:
	    if (((Allctr_t *) a1)->thread_safe)
		return (UWord) erts_alcu_alloc_ts(ERTS_ALC_T_TEST,
							  (void *) a1,
							  (Uint) a2);
	    else
		return (UWord) erts_alcu_alloc(ERTS_ALC_T_TEST,
						       (void *) a1,
						       (Uint) a2);
	case 0xf01:
	    if (((Allctr_t *) a1)->thread_safe)
		return (UWord) erts_alcu_realloc_ts(ERTS_ALC_T_TEST,
							    (void *) a1,
							    (void *) a2,
							    (Uint) a3);
	    else
		return (UWord) erts_alcu_realloc(ERTS_ALC_T_TEST,
							 (void *) a1,
							 (void *) a2,
							 (Uint) a3);
	case 0xf02:
	    if (((Allctr_t *) a1)->thread_safe)
		erts_alcu_free_ts(ERTS_ALC_T_TEST, (void *) a1, (void *) a2);
	    else
		erts_alcu_free(ERTS_ALC_T_TEST, (void *) a1, (void *) a2);
	    return 0;
	case 0xf03: {
	    Allctr_t *allctr;
	    struct au_init init;

	    SET_DEFAULT_ALLOC_OPTS(&init);
	    init.enable = 1;
	    init.astrat = ERTS_ALC_S_GOODFIT;
	    init.init.util.name_prefix = (char *) a1;
	    init.init.util.alloc_no = ERTS_ALC_A_TEST;
	    init.init.util.alloc_strat = init.astrat;
	    init.init.util.ts = 1;
	    if ((char **) a3) {
		char **argv = (char **) a3;
		int i = 0;
		while (argv[i]) {
		    if (argv[i][0] == '-' && argv[i][1] == 't')
			handle_au_arg(&init, &argv[i][2], argv, &i, 0);
		    else
			return (UWord) NULL;
		    i++;
		}
	    }

	    switch (init.astrat) {
	    case ERTS_ALC_S_GOODFIT:
		allctr = erts_gfalc_start((GFAllctr_t *)
					  erts_alloc(ERTS_ALC_T_TEST,
						     sizeof(GFAllctr_t)),
					  &init.init.gf,
					  &init.init.util);
		break;
	    case ERTS_ALC_S_BESTFIT:
		allctr = erts_bfalc_start((BFAllctr_t *)
					  erts_alloc(ERTS_ALC_T_TEST,
						     sizeof(BFAllctr_t)),
					  &init.init.bf,
					  &init.init.util);
		break;
	    case ERTS_ALC_S_AFIT:
		allctr = erts_afalc_start((AFAllctr_t *)
					  erts_alloc(ERTS_ALC_T_TEST,
							    sizeof(AFAllctr_t)),
					  &init.init.af,
					  &init.init.util);
		break;
	    case ERTS_ALC_S_FIRSTFIT:
		allctr = erts_aoffalc_start((AOFFAllctr_t *)
					  erts_alloc(ERTS_ALC_T_TEST,
						     sizeof(AOFFAllctr_t)),
					  &init.init.aoff,
					  &init.init.util);
		break;

	    default:
		ASSERT(0);
		allctr = NULL;
		break;
	    }

	    return (UWord) allctr;
	}
	case 0xf04:
	    erts_alcu_stop((Allctr_t *) a1);
	    erts_free(ERTS_ALC_T_TEST, (void *) a1);
	    break;
	case 0xf05: return (UWord) 1;
	case 0xf06: return (UWord) ((Allctr_t *) a1)->thread_safe;
#ifdef ETHR_NO_FORKSAFETY
	case 0xf07: return (UWord) 0;
#else
	case 0xf07: return (UWord) ((Allctr_t *) a1)->thread_safe;
#endif
	case 0xf08: {
	    ethr_mutex *mtx = erts_alloc(ERTS_ALC_T_TEST, sizeof(ethr_mutex));
	    if (ethr_mutex_init(mtx) != 0)
		ERTS_ALC_TEST_ABORT;
	    return (UWord) mtx;
	}
	case 0xf09: {
	    ethr_mutex *mtx = (ethr_mutex *) a1;
	    if (ethr_mutex_destroy(mtx) != 0)
		ERTS_ALC_TEST_ABORT;
	    erts_free(ERTS_ALC_T_TEST, (void *) mtx);
	    break;
	}
	case 0xf0a:
	    ethr_mutex_lock((ethr_mutex *) a1);
	    break;
	case 0xf0b:
	    ethr_mutex_unlock((ethr_mutex *) a1);
	    break;
	case 0xf0c: {
	    ethr_cond *cnd = erts_alloc(ERTS_ALC_T_TEST, sizeof(ethr_cond));
	    if (ethr_cond_init(cnd) != 0)
		ERTS_ALC_TEST_ABORT;
	    return (UWord) cnd;
	}
	case 0xf0d: {
	    ethr_cond *cnd = (ethr_cond *) a1;
	    if (ethr_cond_destroy(cnd) != 0)
		ERTS_ALC_TEST_ABORT;
	    erts_free(ERTS_ALC_T_TEST, (void *) cnd);
	    break;
	}
	case 0xf0e:
	    ethr_cond_broadcast((ethr_cond *) a1);
	    break;
	case 0xf0f: {
	    int res;
	    do {
		res = ethr_cond_wait((ethr_cond *) a1, (ethr_mutex *) a2);
	    } while (res == EINTR);
	    break;
	}
	case 0xf10: {
	    ethr_tid *tid = erts_alloc(ERTS_ALC_T_TEST, sizeof(ethr_tid));
	    if (ethr_thr_create(tid,
				(void * (*)(void *)) a1,
				(void *) a2,
				NULL) != 0)
		ERTS_ALC_TEST_ABORT;
	    return (UWord) tid;
	}
	case 0xf11: {
	    ethr_tid *tid = (ethr_tid *) a1;
	    if (ethr_thr_join(*tid, NULL) != 0)
		ERTS_ALC_TEST_ABORT;
	    erts_free(ERTS_ALC_T_TEST, (void *) tid);
	    break;
	}
	case 0xf12:
	    ethr_thr_exit((void *) a1);
	    ERTS_ALC_TEST_ABORT;
	    break;
	case 0xf13: return (UWord) 1;
	case 0xf14: return (UWord) erts_alloc(ERTS_ALC_T_TEST, (Uint)a1);

	case 0xf15: erts_free(ERTS_ALC_T_TEST, (void*)a1); return 0;

        case 0xf16: return (UWord) erts_realloc(ERTS_ALC_T_TEST, (void*)a1, (Uint)a2);

	case 0xf17: {
            Uint extra_hdr_sz = UNIT_CEILING((Uint)a1);
	    ErtsAllocatorThrSpec_t* ts = &erts_allctr_thr_spec[ERTS_ALC_A_TEST];
	    Uint offset = ts->allctr[0]->mbc_header_size;
	    void* orig_creating_mbc = ts->allctr[0]->creating_mbc;
	    void* orig_destroying_mbc = ts->allctr[0]->destroying_mbc;
	    void* new_creating_mbc = *(void**)a2; /* inout arg */
	    void* new_destroying_mbc = *(void**)a3; /* inout arg */
	    int i;

	    for (i=0; i < ts->size; i++) {
		Allctr_t* ap = ts->allctr[i];
		if (ap->mbc_header_size != offset
		    || ap->creating_mbc != orig_creating_mbc
		    || ap->destroying_mbc != orig_destroying_mbc
		    || ap->mbc_list.first != NULL)
		    return -1;
	    }
	    for (i=0; i < ts->size; i++) {
		ts->allctr[i]->mbc_header_size += extra_hdr_sz;
		ts->allctr[i]->creating_mbc = new_creating_mbc;
		ts->allctr[i]->destroying_mbc = new_destroying_mbc;
	    }
	    *(void**)a2 = orig_creating_mbc;
	    *(void**)a3 = orig_destroying_mbc;
	    return offset;
	}
	case 0xf18: {
	    ErtsAllocatorThrSpec_t* ts = &erts_allctr_thr_spec[ERTS_ALC_A_TEST];
	    return ts->allctr[0]->largest_mbc_size;
	}
	default:
	    break;
	}
	return (UWord) 0;
    default:
	break;
    }

    ASSERT(0);
    return ~((UWord) 0);
}