Ejemplo n.º 1
0
void *apmalloc(size_t size) {
    if (size == 0) return NULL;

    size_t request_size = ALIGN(size + sizeof(header_t));

    // if it's more than our last bin's capacity, just mmap it
    if (request_size >= (1 << MAX_BINS)) {
        request_size = round_to_next_page(request_size);

        void *ptr = MMAP(request_size);
        if (ptr == MAP_FAILED) return NULL;

        header_t *header = (header_t*)ptr;
        header->size = request_size;
        return (void*)(header + 1);
    }

    // look for free blocks in our lists
    for (unsigned int request_bin = bin_index(request_size); request_bin < MAX_BINS; request_bin++) {
        header_t *candidate = free_list[request_bin];

        while (candidate != NULL) {
            // we found a suitable block
            if (candidate->size >= request_size) {
                // take this block out of the free list
                if (candidate->prev) candidate->prev->next = candidate->next;
                if (candidate->next) candidate->next->prev = candidate->prev;
                if (!(candidate->prev || candidate->next)) free_list[request_bin] = NULL;

                // if there's a remainder, add it back to the appropriate list
                if (candidate->size > request_size) {
                    header_t *remainder = (header_t*)((char*)candidate + request_size);
                    remainder->size = candidate->size - request_size;
                    apfree(remainder + 1);

                    candidate->size = request_size;
                }

                return (void*)(candidate + 1);
            }

            candidate = candidate->next;
        }
    }

    // no block big enough found, request and split a big chunk
    void *ptr = MMAP(PAGE_SIZE);
    if (ptr == MAP_FAILED) return NULL;

    header_t *remainder = (header_t*)((char*)ptr + request_size);
    remainder->size = PAGE_SIZE - request_size;
    apfree(remainder + 1);

    header_t *header = (header_t*)ptr;
    header->size = request_size;
    return (void*)(header + 1);
}
Ejemplo n.º 2
0
void apfree(void *ptr) {
    if (ptr == NULL) return;

    header_t *header = (header_t*)ptr - 1;

    // if it's bigger than our last bin's capacity, we used mmap
    if (header->size >= (1 << MAX_BINS)) {
        munmap(header, header->size);
    } else {
        unsigned int index = bin_index(header->size);
        header_t *previous = NULL, *current = free_list[index];

        while (current != NULL && current < header) {
            previous = current;
            current = current->next;
        }

        if (previous) previous->next = header;
        else free_list[index] = header;
        header->prev = previous;

        if (current) current->prev = header;
        header->next = current;

        // coalesce
        if ((char*)header + header->size == (char*)current) {
            header->size += current->size;
            header->next = current->next;
            if (current->next) current->next->prev = header;
        }

        if (previous && ((char*)previous + previous->size == (char*)header)) {
            previous->size += header->size;
            previous->next = header->next;
            if (header->next) header->next->prev = previous;
        }
    }
}
Ejemplo n.º 3
0
Archivo: pmf.c Proyecto: ilyak/wham
void read_input(void)
{
	FILE *in;
	int i, j, *nbin, *nsim;

	in = input ? fopen(input, "r") : stdin;
	if (in == NULL)
		message_fatal("Unable to open input file");

	skip_comment(in);

	if (fscanf(in, "%d", &sim_count) != 1)
		message_fatal("Unable to read number of simulations");

	if (sim_count <= 0)
		message_fatal("Expected positive number of simulations");

	bias_x = xmalloc(sim_count * sizeof(*bias_x));
	bias_k = xmalloc(sim_count * sizeof(*bias_k));
	log_nbin = xmalloc(bin_count * sizeof(*log_nbin));
	log_nsim = xmalloc(sim_count * sizeof(*log_nsim));
	nbin = xmalloc(bin_count * sizeof(*nbin));
	nsim = xmalloc(sim_count * sizeof(*nsim));

	for (i = 0; i < bin_count; i++)
		nbin[i] = 0;

	for (i = 0; i < sim_count; i++) {
		double x;
		int npt;

		if (fscanf(in, "%lf %lf", &bias_x[i], &bias_k[i]) != 2)
			message_fatal("Error reading bias info");

		if (fscanf(in, "%d", &npt) != 1)
			message_fatal("Error reading point count");

		if (npt <= 0)
			message_fatal("Expected positive number of points");

		nsim[i] = 0;

		for (j = 0; j < npt; j++) {
			if (fscanf(in, "%lf", &x) != 1)
				message_fatal("Error reading data points");

			if (period > 0) {
				if (x > 0)
					while (x > period)
						x -= period;
				else
					while (x < 0)
						x += period;
			}
			if (x > hist_min && x < hist_max) {
				nbin[bin_index(x)]++;
				nsim[i]++;
			}
		}
		message(V_VERBOSE, "Added %d of %d points from window %d",
		    nsim[i], npt, i + 1);
	}

	for (i = 0; i < bin_count; i++)
		log_nbin[i] = log(nbin[i]);
	for (i = 0; i < sim_count; i++)
		log_nsim[i] = log(nsim[i]);

	if (in != stdin)
		fclose(in);
	free(nbin);
	free(nsim);
}