/* bufnew • allocation of a new buffer */ struct buf * #ifndef TRACK_BUFFER_DEBUG bufnew(size_t unit) { #else bufnew_(size_t unit, const char *file, int line) { struct buf_debug_data *bdd; #endif struct buf *ret; ret = malloc(sizeof (struct buf)); if (ret) { #ifdef BUFFER_STATS buffer_stat_nb += 1; #endif #ifdef TRACK_BUFFERS parr_push(&all_buffers, ret); #endif ret->data = 0; ret->size = ret->asize = 0; ret->ref = 1; ret->unit = unit; } #ifdef TRACK_BUFFER_DEBUG if (ret) { bdd = arr_item(&all_buffers, arr_newitem(&all_buffers)); bdd->buf = ret; bdd->dupped = 0; bdd->ctime = time(0); bdd->file = file; bdd->line = line; } return ret; } #else return ret; }
/* new_work_buffer • get a new working buffer from the stack or create one */ static struct buf * new_work_buffer(struct render *rndr) { struct buf *ret = 0; if (rndr->work.size < rndr->work.asize) { ret = rndr->work.item[rndr->work.size ++]; ret->size = 0; } else { ret = bufnew(WORK_UNIT); parr_push(&rndr->work, ret); } return ret; }
static inline struct buf * rndr_newbuf(struct render *rndr) { struct buf *work = NULL; if (rndr->work.size < rndr->work.asize) { work = rndr->work.item[rndr->work.size++]; work->size = 0; } else { work = bufnew(WORK_UNIT); parr_push(&rndr->work, work); } return work; }
/* bufdup • buffer duplication */ struct buf * #ifndef TRACK_BUFFER_DEBUG bufdup(const struct buf *src, size_t dupunit) { #else bufdup_(const struct buf *src, size_t dupunit, const char *file, int line) { struct buf_debug_data *bdd; #endif size_t blocks; struct buf *ret; if (src == 0) return 0; ret = malloc(sizeof (struct buf)); if (ret == 0) return 0; ret->unit = dupunit; ret->size = src->size; ret->ref = 1; if (!src->size) { #ifdef BUFFER_STATS buffer_stat_nb += 1; #endif ret->asize = 0; ret->data = 0; return ret; } blocks = (src->size + dupunit - 1) / dupunit; ret->asize = blocks * dupunit; ret->data = malloc(ret->asize); if (ret->data == 0) { free(ret); return 0; } memcpy(ret->data, src->data, src->size); #ifdef BUFFER_STATS buffer_stat_nb += 1; buffer_stat_alloc_bytes += ret->asize; #endif #ifdef TRACK_BUFFERS parr_push(&all_buffers, ret); #endif #ifdef TRACK_BUFFER_DEBUG bdd = arr_item(&all_buffers, arr_newitem(&all_buffers)); bdd->buf = ret; bdd->dupped = 1; bdd->ctime = time(0); bdd->file = file; bdd->line = line; return ret; } #else return ret; }