Exemplo n.º 1
0
// Set const data to en empty buffer
BSP_DECLARE(size_t) bsp_buffer_set_const(BSP_BUFFER *b, const char *data, ssize_t len)
{
    if (!b || !data || B_ISCONST(b))
    {
        return 0;
    }

    if (len < 0)
    {
        len = strnlen(data, _BSP_MAX_UNSIZED_STRLEN);
    }

    if (B_DATA(b))
    {
        bsp_free(B_DATA(b));
    }

    B_DATA(b) = (char *) data;
    B_SIZE(b) = 0;
    B_LEN(b) = len;

    // Set to const
    b->is_const = BSP_TRUE;

    return len;
}
Exemplo n.º 2
0
// Cancellation a buffer
BSP_DECLARE(void) bsp_del_buffer(BSP_BUFFER *b)
{
    if (b)
    {
        if (!B_ISCONST(b))
        {
            if (_BSP_BUFFER_HIGHWATER < B_SIZE(b))
            {
                // Buffer too big, just clean
                bsp_free(B_DATA(b));
                B_DATA(b) = NULL;
                B_SIZE(b) = 0;
                B_LEN(b) = 0;
                B_NOW(b) = 0;
            }

            if (_BSP_BUFFER_UNSATURATION < (B_SIZE(b) - B_LEN(b)))
            {
                _shrink_buffer(b);
            }
        }
        else
        {
            B_DATA(b) = NULL;
            B_SIZE(b) = 0;
        }

        bsp_mempool_free(mp_buffer, (void *) b);
    }

    return;
}
Exemplo n.º 3
0
BSP_PRIVATE(int) _shrink_buffer(BSP_BUFFER *b)
{
    if (b)
    {
        size_t new_size = 2 << (int) log2(B_LEN(b));
        if (new_size < B_SIZE(b))
        {
            char *new_data = bsp_realloc(B_DATA(b), new_size);
            if (new_data)
            {
                B_DATA(b) = new_data;
                B_SIZE(b) = new_size;

                return BSP_RTN_SUCCESS;
            }

            return BSP_RTN_ERR_MEMORY;
        }
        else
        {
            // May not shrink
            return BSP_RTN_SUCCESS;
        }
    }

    return BSP_RTN_ERR_GENERAL;
}
Exemplo n.º 4
0
/* Mempool freer */
BSP_PRIVATE(void) _buffer_free(void *item)
{
    BSP_BUFFER *b = (BSP_BUFFER *) item;
    if (b)
    {
        if (B_DATA(b) && !B_ISCONST(b))
        {
            bsp_free(B_DATA(b));
        }

        bsp_free(b);
    }

    return;
}
Exemplo n.º 5
0
// Read file descriptor to buffer
BSP_DECLARE(ssize_t) bsp_buffer_io_read(BSP_BUFFER *b, int fd, size_t len)
{
    if (!b || !fd || !len)
    {
        return 0;
    }

    size_t need = B_LEN(b) + len;
    if (need > B_SIZE(b))
    {
        if (BSP_RTN_SUCCESS != _enlarge_buffer(b, need))
        {
            // Enlarge error
            return 0;
        }
    }

    // Try read
    ssize_t ret = read(fd, B_DATA(b) + B_LEN(b), len);
    if (ret > 0)
    {
        bsp_trace_message(BSP_TRACE_DEBUG, _tag_, "Read %d bytes from fd %d to buffer", (int) ret, fd);
        B_LEN(b) += ret;
    }

    return ret;
}
Exemplo n.º 6
0
// Append data to buffer
BSP_DECLARE(size_t) bsp_buffer_append(BSP_BUFFER *b, const char *data, ssize_t len)
{
    if (!b || !data || B_ISCONST(b))
    {
        return 0;
    }

    if (len < 0)
    {
        len = strnlen(data, _BSP_MAX_UNSIZED_STRLEN);
    }

    size_t need = B_LEN(b) + len;
    if (need > B_SIZE(b))
    {
        // Space not enough, realloc buffer
        if (BSP_RTN_SUCCESS != _enlarge_buffer(b, need))
        {
            // Enlarge error
            return 0;
        }
    }

    memcpy(B_DATA(b) + B_LEN(b), data, len);
    B_LEN(b) = need;

    return len;
}
Exemplo n.º 7
0
void print_block_info(struct block *ptr) {
	struct block *b = ptr;
	printf("pos = %p, ", ptr);
	printf("state = %u, k_size = %lu\n", b->state, b->k_size);
	printf("data =\n");
	LOG("CHECK pow=%lu, bsize=%lu\n", pow2(b->k_size), B_SIZE);
	dump_data(B_DATA(ptr), B_DATA_SIZE(ptr));
	printf("\n");
}
Exemplo n.º 8
0
static int init_pool() {
	/* Get current heap break address */
	if ((mp.base_addr = sbrk(0)) == (void *) -1) {
		perror("sbrk");
		return -1;
	}

	/* First block on heap will contain 'avail' array */
	/* First-block initialization for the avail array containing heads of lists with available memory, it has length of (max pool size + 1) */
	/* Logarithm of the space, we can adress */
	mp.max_size = CHAR_BIT*sizeof(void *);
	/* We want to have available pointers to all the memory we can adress */
	mp.init_size = get_pow(B_SIZE + (mp.max_size + 1)*(sizeof(struct avail_head)));
	if (sbrk(pow2(mp.init_size)) == (void *) -1) {
		perror("sbrk");
		return -1;
	}
	mp.pool_size = mp.init_size;

	/* Initialize the first block, which will contain 'avail' array */
	struct block *first_b;
	first_b = (struct block *) mp.base_addr;
	first_b->state = USED;
	first_b->k_size = mp.init_size;

	LOG("--## POOL INIT INFO ##--\n");
	LOG("## Heap memory begins at base_addr = %p\n", mp.base_addr);
	LOG("## Size of the first block is init_size = 2^%lu = %luB\n", mp.init_size, pow2(mp.init_size));
	LOG("## Maximum pool size is max_size = 2^%lu = %luB\n", mp.max_size, -1L);

	/* Init 'avail', array of cyclic linked list */
	mp.avail = (struct avail_head *) B_DATA(first_b);
	int i;
	for (i=0; i <= mp.max_size; i++) {
		mp.avail[i].next = (struct block *) &mp.avail[i];
		mp.avail[i].prev = (struct block *) &mp.avail[i];
	}

	first_b->prev = (struct block *) &mp.avail[first_b->k_size];
	first_b->next = (struct block *) &mp.avail[first_b->k_size];

	//TODO WIP
	int err;
	if ((err = pthread_create(&cleaner_th, NULL, cleaning_work, NULL)) != 0) {
		printf("pthread_create() ERROR %d!\n", err);
		return -1;
	}
	if ((err = pthread_detach(cleaner_th)) != 0) {
		printf("pthread_detach() ERROR %d!\n", err);
		return -1;
	}
	//TODO WIP
	LOG("--## END OF POOL INIT INFO ##--\n");

	return 0;
}
Exemplo n.º 9
0
// Read all data from file descriptor to buffer
BSP_DECLARE(ssize_t) bsp_buffer_io_read_all(BSP_BUFFER *b, int fd)
{
    if (!b || !fd)
    {
        return 0;
    }

    ssize_t len = 0, tlen = 0;
    while (BSP_TRUE)
    {
        size_t need = B_LEN(b) + _BSP_FD_READ_ONCE;
        if (need > B_SIZE(b))
        {
            if (BSP_RTN_SUCCESS != _enlarge_buffer(b, need))
            {
                // Enlarge error
                break;
            }
        }

        len = read(fd, B_DATA(b) + B_LEN(b), _BSP_FD_READ_ONCE);
        if (len < 0)
        {
            if (EINTR == errno || EWOULDBLOCK == errno || EAGAIN == errno)
            {
                 // Break
                break;
            }
        }
        else if (0 == len)
        {
            // TCP FIN
            tlen = 0;
            break;
        }
        else
        {
            // Data already in buffer -_-
            tlen += len;
            B_LEN(b) += len;
            bsp_trace_message(BSP_TRACE_DEBUG, _tag_, "Read %d bytes from fd %d to buffer", (int) len, fd);
            if (len < _BSP_FD_READ_ONCE)
            {
                // All gone
                break;
            }
        }
    }

    return tlen;
}
Exemplo n.º 10
0
BSP_PRIVATE(int) _enlarge_buffer(BSP_BUFFER *b, size_t size)
{
    if (b && size > B_SIZE(b))
    {
        size_t new_size = 2 << bsp_log2(size);
        char *new_data = bsp_realloc(B_DATA(b), new_size);
        if (new_data)
        {
            B_DATA(b) = new_data;
            B_SIZE(b) = new_size;

            return BSP_RTN_SUCCESS;
        }
        else
        {
            bsp_trace_message(BSP_TRACE_CRITICAL, _tag_, "Enlarge buffer to %llu bytes failed", (unsigned long long int) new_size);
        }

        return BSP_RTN_ERR_MEMORY;
    }

    return BSP_RTN_ERR_GENERAL;
}
Exemplo n.º 11
0
// Fill seriate character to buffer
BSP_DECLARE(size_t) bsp_buffer_fill(BSP_BUFFER *b, int code, size_t len)
{
    if (!b || !len)
    {
        return 0;
    }

    size_t need = B_LEN(b) + len;
    if (need > B_SIZE(b))
    {
        if (BSP_RTN_SUCCESS != _enlarge_buffer(b, need))
        {
            // Enlarge error
            return 0;
        }
    }

    memset(B_DATA(b) + B_LEN(b), code, len);
    B_LEN(b) = need;

    return len;
}
Exemplo n.º 12
0
static void *alloc(unsigned long size_pow, enum m_state state) {
	/* Pool not initialized */
	if (mp.base_addr == NULL) {
		/* Try to initialize it */
		if (init_pool() == -1) {
			errno = ENOMEM;
			return NULL;
		}
	}

//	LOG("BEFORE ALLOC\n");
//	print_avail_map();

	/* Size in power of 2, which needs to be reserved */
	//LOG("Request for 2^%lu = %luB\n", size_pow, pow2(size_pow));
	/* Size of the first suitable block which is available (in pow of 2) */
	unsigned long j;
	/* Find the value of 'j' in available memory space if possible */
	//LOG("--## FINDING J ##--\n");
	for (j=size_pow; j < mp.pool_size; j++) {
		if (!list_empty(&mp.avail[j])) {
			break;
		}
		//LOG("j=%lu not suitable\n", j);
	}
	/* Do we need to enlarge the pool? - by making buddy for existing largest block */
	//LOG("--## ENLARGING ##--\n");
	while (list_empty(&mp.avail[j])) {
		//LOG("j=%lu <= pool_size=%lu <= max=%lu\n", j, mp.pool_size, mp.max_size);
		/* Cannot adress this amount of memory */
		if (get_pow((unsigned long)mp.base_addr) + size_pow >= mp.max_size) {
		//TODO ktery pouzit?
		//if (mp.max_size >= mp.max_size) {
			LOG("Maximum size reached!\n");
			errno = ENOMEM;
			return NULL;
		}
		//LOG("Enlarging the pool.\n");
		void *new_addr;
		if ((new_addr = sbrk(pow2(mp.pool_size))) == (void *)-1) {
			LOG("sbrk pool-enlarge error!\n");
			errno = ENOMEM;
			return NULL;
		}
		//TODO bez prepsani zpusobuje neporadek s valgrindem
		//memset(new_addr, 0, pow2(mp.pool_size));

		/* Pool was enlarged, we have twice as much space */
		mp.pool_size++;
		/* New memory block, buddy for previous block, will live in this space */
		//LOG("new_addr = %p\n", new_addr);
		struct block *nb = (struct block *) new_addr;
		nb->state = FREE;
		nb->k_size = mp.pool_size - 1;
		//LOG("k_size = %lu\n", nb->k_size);
	
		/* Avail array must be edited, we've got new free block of size 2^(nb->k_size) */
		struct block *p;
		p = mp.avail[nb->k_size].next;
		//LOG("p point %p head to %p\n", p, &mp.avail[nb->k_size]);
		nb->next = p;
		p->prev = nb;
		nb->prev = (struct block *) &mp.avail[nb->k_size];
		mp.avail[nb->k_size].next = nb;
	}

	/* We now have the 'j' value set */
	//LOG("--## REMOVING BLOCK FROM AVAIL ARRAY ##--\n");
	/* Remove this block from avail array */
	struct block *l, *p;
	l = mp.avail[j].prev;
	//LOG("L position = %p\n", l);
	p = l->prev;
	mp.avail[j].prev = p;
	p->next = (struct block *) &mp.avail[j];
	enum m_state block_state = l->state;
	l->state = USED;

	/* Now we need to divide the block if space in it is too large */
	//LOG("--## DIVIDING BLOCK ##--\n");
	while (j != size_pow) {
		//LOG("divination for j=%lu\n", j);
		j--;
		p = (struct block *)((unsigned long)l + pow2(j));
		//LOG("pointering to %p\n", p);
		p->state = FREE;
		p->k_size = j;
		p->prev = (struct block *) &mp.avail[j];
		p->next = (struct block *) &mp.avail[j];
		/* Add this block into avail array */
		mp.avail[j].prev = p;
		mp.avail[j].next = p;
	}
	l->k_size = size_pow;
	
	/* Does the memory need to be cleared? */
	if (state == ZERO && block_state != ZERO) {
		memset(B_DATA(l), 0, B_DATA_SIZE(l));
	}

//	LOG("AFTER ALLOC\n");
//	print_avail_map();
//	LOG("\n");

	return B_DATA(l);
}