#include <stdio.h>
char *
-bb_vprintf_at(bb_t *bb, uint ofs, const char *fmt, va_list args)
+bb_vprintf_at(bb_t *bb, size_t ofs, const char *fmt, va_list args)
{
bb_grow(bb, ofs + 1);
va_list args2;
}
while (cnt < 0);
}
- else if ((uns)cnt >= bb->len - ofs)
+ else if ((uint)cnt >= bb->len - ofs)
{
bb_do_grow(bb, ofs + cnt + 1);
va_copy(args2, args);
}
char *
-bb_printf_at(bb_t *bb, uint ofs, const char *fmt, ...)
+bb_printf_at(bb_t *bb, size_t ofs, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
byte *buffer, *bufend; /* Start and end of the buffer */
char *name; /* File name (used for error messages) */
ucw_off_t pos; /* Position of bstop in the file */
- uns flags; /* See enum fb_flags */
+ uint flags; /* See enum fb_flags */
int (*refill)(struct fastbuf *); /* Get a buffer with new data, returns 0 on EOF */
void (*spout)(struct fastbuf *); /* Write buffer data to the file */
int (*seek)(struct fastbuf *, ucw_off_t, int);/* Slow path for @bseek(), buffer already flushed; returns success */
void (*close)(struct fastbuf *); /* Close the stream */
- int (*config)(struct fastbuf *, uns, int); /* Configure the stream */
+ int (*config)(struct fastbuf *, uint, int); /* Configure the stream */
int can_overwrite_buffer; /* Can the buffer be altered? 0=never, 1=temporarily, 2=permanently */
struct resource *res; /* The fastbuf can be tied to a resource pool */
};
*/
struct fb_params {
enum fb_type type; /* The chosen back-end */
- uns buffer_size; /* 0 for default size */
- uns keep_back_buf; /* FB_STD: optimize for bi-directional access */
- uns read_ahead; /* FB_DIRECT options */
- uns write_back;
+ uint buffer_size; /* 0 for default size */
+ uint keep_back_buf; /* FB_STD: optimize for bi-directional access */
+ uint read_ahead; /* FB_DIRECT options */
+ uint write_back;
struct asio_queue *asio;
};
* up any parameters, there is a couple of shortcuts.
***/
- struct fastbuf *bopen(const char *name, uns mode, uns buflen); /** Equivalent to @bopen_file() with `FB_STD` back-end. **/
- struct fastbuf *bopen_try(const char *name, uns mode, uns buflen); /** Equivalent to @bopen_file_try() with `FB_STD` back-end. **/
- struct fastbuf *bopen_tmp(uns buflen); /** Equivalent to @bopen_tmp_file() with `FB_STD` back-end. **/
- struct fastbuf *bfdopen(int fd, uns buflen); /** Equivalent to @bopen_fd() with `FB_STD` back-end. **/
- struct fastbuf *bfdopen_shared(int fd, uns buflen); /** Like @bfdopen(), but it does not close the @fd on @bclose(). **/
+ struct fastbuf *bopen(const char *name, uint mode, uint buflen); /** Equivalent to @bopen_file() with `FB_STD` back-end. **/
+ struct fastbuf *bopen_try(const char *name, uint mode, uint buflen); /** Equivalent to @bopen_file_try() with `FB_STD` back-end. **/
+ struct fastbuf *bopen_tmp(uint buflen); /** Equivalent to @bopen_tmp_file() with `FB_STD` back-end. **/
+ struct fastbuf *bfdopen(int fd, uint buflen); /** Equivalent to @bopen_fd() with `FB_STD` back-end. **/
+ struct fastbuf *bfdopen_shared(int fd, uint buflen); /** Like @bfdopen(), but it does not close the @fd on @bclose(). **/
/***
* === Temporary files [[fbtemp]]
/* Internal functions of some file back-ends */
- struct fastbuf *bfdopen_internal(int fd, const char *name, uns buflen);
- struct fastbuf *bfmmopen_internal(int fd, const char *name, uns mode);
+ struct fastbuf *bfdopen_internal(int fd, const char *name, uint buflen);
+ struct fastbuf *bfmmopen_internal(int fd, const char *name, uint mode);
#ifdef CONFIG_UCW_FB_DIRECT
- extern uns fbdir_cheat;
+ extern uint fbdir_cheat;
struct asio_queue;
- struct fastbuf *fbdir_open_fd_internal(int fd, const char *name, struct asio_queue *io_queue, uns buffer_size, uns read_ahead, uns write_back);
+ struct fastbuf *fbdir_open_fd_internal(int fd, const char *name, struct asio_queue *io_queue, uint buffer_size, uint read_ahead, uint write_back);
#endif
void bclose_file_helper(struct fastbuf *f, int fd, int is_temp_file);
* number of bytes. This is frequently used for reading from sockets.
***/
- struct fastbuf *bopen_limited_fd(int fd, uns bufsize, uns limit); /** Create a fastbuf which reads at most @limit bytes from @fd. **/
+ struct fastbuf *bopen_limited_fd(int fd, uint bufsize, uint limit); /** Create a fastbuf which reads at most @limit bytes from @fd. **/
/***
* === Fastbufs on in-memory streams [[fbmem]]
* an arbitrary number of fastbuf for reading from the stream.
***/
- struct fastbuf *fbmem_create(uns blocksize); /** Create stream and return its writing fastbuf. **/
+ struct fastbuf *fbmem_create(uint blocksize); /** Create stream and return its writing fastbuf. **/
struct fastbuf *fbmem_clone_read(struct fastbuf *f); /** Given a writing fastbuf, create a new reading fastbuf. **/
/***
* It is not possible to close this fastbuf. This implies that no tying to
* resources takes place.
*/
- void fbbuf_init_read(struct fastbuf *f, byte *buffer, uns size, uns can_overwrite);
+ void fbbuf_init_read(struct fastbuf *f, byte *buffer, uint size, uint can_overwrite);
/**
* Creates a write-only fastbuf which writes into a provided memory buffer.
* It is not possible to close this fastbuf. This implies that no tying to
* resources takes place.
*/
- void fbbuf_init_write(struct fastbuf *f, byte *buffer, uns size);
+ void fbbuf_init_write(struct fastbuf *f, byte *buffer, uint size);
- static inline uns fbbuf_count_written(struct fastbuf *f) /** Calculates, how many bytes were already written into the buffer. **/
+ static inline uint fbbuf_count_written(struct fastbuf *f) /** Calculates, how many bytes were already written into the buffer. **/
{
return f->bptr - f->bstop;
}
struct mempool;
- struct fastbuf *fbgrow_create(unsigned basic_size); /** Create the growing buffer pre-allocated to @basic_size bytes. **/
- struct fastbuf *fbgrow_create_mp(struct mempool *mp, unsigned basic_size); /** Create the growing buffer pre-allocated to @basic_size bytes. **/
+ struct fastbuf *fbgrow_create(uint basic_size); /** Create the growing buffer pre-allocated to @basic_size bytes. **/
+ struct fastbuf *fbgrow_create_mp(struct mempool *mp, uint basic_size); /** Create the growing buffer pre-allocated to @basic_size bytes. **/
void fbgrow_reset(struct fastbuf *b); /** Reset stream and prepare for writing. **/
void fbgrow_rewind(struct fastbuf *b); /** Prepare for reading (of already written data). **/
* @fbgrow_rewind()) to return the pointer to internal buffer and its length in
* bytes. The returned buffer can be invalidated by further requests.
**/
- uns fbgrow_get_buf(struct fastbuf *b, byte **buf);
+ uint fbgrow_get_buf(struct fastbuf *b, byte **buf);
/***
* === Fastbuf on memory pools [[fbpool]]
* Start a new continuous block and prepare for writing (see <<mempool:mp_start()>>).
* Provide the memory pool you want to use for this block as @mp.
**/
-void fbpool_start(struct fbpool *fb, struct mempool *mp, uint init_size);
+void fbpool_start(struct fbpool *fb, struct mempool *mp, size_t init_size);
/**
* Close the block and return the address of its start (see <<mempool:mp_end()>>).
* The length can be determined by calling <<mempool:mp_size(mp, ptr)>>.
struct fastbuf fb;
struct fb_atomic_file *af;
byte *expected_max_bptr;
- uns slack_size;
+ uint slack_size;
};
/**
*
* The file is closed when all fastbufs using it are closed.
**/
- struct fastbuf *fbatomic_open(const char *name, struct fastbuf *master, uns bufsize, int record_len);
+ struct fastbuf *fbatomic_open(const char *name, struct fastbuf *master, uint bufsize, int record_len);
void fbatomic_internal_write(struct fastbuf *b);
/**
* Creates a new "/dev/null"-like fastbuf.
* Any read attempt returns an EOF, any write attempt is silently ignored.
**/
- struct fastbuf *fbnull_open(uns bufsize);
+ struct fastbuf *fbnull_open(uint bufsize);
/**
* Can be used by any back-end to switch it to the null mode.
* You need to provide at least one byte long buffer for writing.
**/
- void fbnull_start(struct fastbuf *b, byte *buf, uns bufsize);
+ void fbnull_start(struct fastbuf *b, byte *buf, uint bufsize);
/**
* Checks whether a fastbuf has been switched to the null mode.
BCONFIG_KEEP_BACK_BUF, /* Optimize for bi-directional access */
};
- int bconfig(struct fastbuf *f, uns type, int data); /** Configure a fastbuf. Returns previous value. **/
+ int bconfig(struct fastbuf *f, uint type, int data); /** Configure a fastbuf. Returns previous value. **/
/*** === Universal functions working on all fastbuf's [[ffbasic]] ***/
f->bptr--;
}
- void bputc_slow(struct fastbuf *f, uns c);
- static inline void bputc(struct fastbuf *f, uns c) /** Write a single character. **/
+ void bputc_slow(struct fastbuf *f, uint c);
+ static inline void bputc(struct fastbuf *f, uint c) /** Write a single character. **/
{
if (f->bptr < f->bufend)
*f->bptr++ = c;
bputc_slow(f, c);
}
- static inline uns bavailr(struct fastbuf *f) /** Return the length of the cached data to be read. Do not use directly. **/
+ static inline uint bavailr(struct fastbuf *f) /** Return the length of the cached data to be read. Do not use directly. **/
{
return f->bstop - f->bptr;
}
- static inline uns bavailw(struct fastbuf *f) /** Return the length of the buffer available for writing. Do not use directly. **/
+ static inline uint bavailw(struct fastbuf *f) /** Return the length of the buffer available for writing. Do not use directly. **/
{
return f->bufend - f->bptr;
}
- uns bread_slow(struct fastbuf *f, void *b, uns l, uns check);
+ uint bread_slow(struct fastbuf *f, void *b, uint l, uint check);
/**
* Read at most @l bytes of data into @b.
* Returns number of bytes read.
* 0 means end of file.
*/
- static inline uns bread(struct fastbuf *f, void *b, uns l)
+ static inline uint bread(struct fastbuf *f, void *b, uint l)
{
if (bavailr(f) >= l)
{
* If at the end of file, it returns 0.
* If there are data, but less than @l, it raises `ucw.fb.eof`.
*/
- static inline uns breadb(struct fastbuf *f, void *b, uns l)
+ static inline uint breadb(struct fastbuf *f, void *b, uint l)
{
if (bavailr(f) >= l)
{
return bread_slow(f, b, l, 1);
}
- void bwrite_slow(struct fastbuf *f, const void *b, uns l);
- static inline void bwrite(struct fastbuf *f, const void *b, uns l) /** Writes buffer @b of length @l into fastbuf. **/
+ void bwrite_slow(struct fastbuf *f, const void *b, uint l);
+ static inline void bwrite(struct fastbuf *f, const void *b, uint l) /** Writes buffer @b of length @l into fastbuf. **/
{
if (bavailw(f) >= l)
{
* Returns pointer to the terminating 0 or NULL on `EOF`.
* Raises `ucw.fb.toolong` if the line is longer than @l.
**/
- char *bgets(struct fastbuf *f, char *b, uns l);
- char *bgets0(struct fastbuf *f, char *b, uns l); /** The same as @bgets(), but for 0-terminated strings. **/
+ char *bgets(struct fastbuf *f, char *b, uint l);
+ char *bgets0(struct fastbuf *f, char *b, uint l); /** The same as @bgets(), but for 0-terminated strings. **/
/**
* Returns either length of read string (excluding the terminator) or -1 if it is too long.
* In such cases exactly @l bytes are read.
*/
- int bgets_nodie(struct fastbuf *f, char *b, uns l);
+ int bgets_nodie(struct fastbuf *f, char *b, uint l);
struct mempool;
struct bb_t;
* Read a string, strip the trailing `\n` and store it into growing buffer @b.
* Raises `ucw.fb.toolong` if the line is longer than @limit.
**/
- uns bgets_bb(struct fastbuf *f, struct bb_t *b, uns limit);
+ uint bgets_bb(struct fastbuf *f, struct bb_t *b, uint limit);
/**
* Read a string, strip the trailing `\n` and store it into buffer allocated from a memory pool.
**/
struct bgets_stk_struct {
struct fastbuf *f;
byte *old_buf, *cur_buf, *src;
- uns old_len, cur_len, src_len;
+ uint old_len, cur_len, src_len;
};
void bgets_stk_init(struct bgets_stk_struct *s);
void bgets_stk_step(struct bgets_stk_struct *s);
bputc(f, '\n');
}
- void bbcopy_slow(struct fastbuf *f, struct fastbuf *t, uns l);
+ void bbcopy_slow(struct fastbuf *f, struct fastbuf *t, uint l);
/**
* Copy @l bytes of data from fastbuf @f to fastbuf @t.
* `UINT_MAX` (`~0U`) means all data, even if more than `UINT_MAX` bytes remain.
**/
- static inline void bbcopy(struct fastbuf *f, struct fastbuf *t, uns l)
+ static inline void bbcopy(struct fastbuf *f, struct fastbuf *t, uint l)
{
if (bavailr(f) >= l && bavailw(t) >= l)
{
bbcopy_slow(f, t, l);
}
- int bskip_slow(struct fastbuf *f, uns len);
- static inline int bskip(struct fastbuf *f, uns len) /** Skip @len bytes without reading them. **/
+ int bskip_slow(struct fastbuf *f, uint len);
+ static inline int bskip(struct fastbuf *f, uint len) /** Skip @len bytes without reading them. **/
{
if (bavailr(f) >= len)
{
* The reading must be ended by @bdirect_read_commit() or @bdirect_read_commit_modified(),
* unless the user did not read or modify anything.
**/
- static inline uns bdirect_read_prepare(struct fastbuf *f, byte **buf)
+ static inline uint bdirect_read_prepare(struct fastbuf *f, byte **buf)
{
if (f->bptr == f->bstop && !f->refill(f))
{
* where we can write to. The operation must be ended by @bdirect_write_commit(),
* unless nothing is written.
**/
- static inline uns bdirect_write_prepare(struct fastbuf *f, byte **buf)
+ static inline uint bdirect_write_prepare(struct fastbuf *f, byte **buf)
{
if (f->bptr == f->bufend)
f->spout(f);
{
if (b->bptr == b->bufend)
{
- uns len = b->bufend - b->buffer;
+ uint len = b->bufend - b->buffer;
b->bstop = b->buffer = mp_expand(FB_POOL(b)->mp);
b->bufend = b->buffer + mp_avail(FB_POOL(b)->mp);
b->bptr = b->buffer + len;
}
void
-fbpool_start(struct fbpool *b, struct mempool *mp, uint init_size)
+fbpool_start(struct fbpool *b, struct mempool *mp, size_t init_size)
{
b->mp = mp;
b->fb.buffer = b->fb.bstop = b->fb.bptr = mp_start(mp, init_size);
struct mempool *mp;
struct fbpool fb;
byte *p;
- uns l;
+ uint l;
mp = mp_new(64);
fbpool_init(&fb);
fbpool_start(&fb, mp, 16);
- for (uns i = 0; i < 1024; i++)
+ for (uint i = 0; i < 1024; i++)
bprintf(&fb.fb, "<hello>");
p = fbpool_end(&fb);
l = mp_size(mp, p);
if (l != 1024 * 7)
ASSERT(0);
- for (uns i = 0; i < 1024; i++)
+ for (uint i = 0; i < 1024; i++)
if (memcmp(p + i * 7, "<hello>", 7))
ASSERT(0);
mp_delete(mp);
#include <string.h>
static char *
-mp_vprintf_at(struct mempool *mp, uint ofs, const char *fmt, va_list args)
+mp_vprintf_at(struct mempool *mp, size_t ofs, const char *fmt, va_list args)
{
char *ret = mp_grow(mp, ofs + 1) + ofs;
va_list args2;
}
while (cnt < 0);
}
- else if ((uns)cnt >= mp_avail(mp) - ofs)
+ else if ((uint)cnt >= mp_avail(mp) - ofs)
{
ret = mp_grow(mp, ofs + cnt + 1) + ofs;
va_copy(args2, args);
char *
mp_append_vprintf(struct mempool *mp, char *ptr, const char *fmt, va_list args)
{
- uint ofs = mp_open(mp, ptr);
+ size_t ofs = mp_open(mp, ptr);
ASSERT(ofs && !ptr[ofs - 1]);
return mp_vprintf_at(mp, ofs - 1, fmt, args);
}
{
if (!s)
return NULL;
- uint l = strlen(s) + 1;
+ size_t l = strlen(s) + 1;
char *t = mp_alloc_fast_noalign(p, l);
memcpy(t, s, l);
return t;
}
void *
-mp_memdup(struct mempool *p, const void *s, uint len)
+mp_memdup(struct mempool *p, const void *s, size_t len)
{
void *t = mp_alloc_fast(p, len);
memcpy(t, s, len);
va_list args, a;
va_start(args, p);
char *x, *y;
- uns cnt = 0;
+ uint cnt = 0;
va_copy(a, args);
while (x = va_arg(a, char *))
cnt++;
- uint *sizes = alloca(cnt * sizeof(uint));
- uint len = 1;
+ size_t *sizes = alloca(cnt * sizeof(*sizes));
+ size_t len = 1;
cnt = 0;
va_end(a);
va_copy(a, args);
}
char *
- mp_strjoin(struct mempool *p, char **a, uns n, uns sep)
+ mp_strjoin(struct mempool *p, char **a, uint n, uint sep)
{
- uint sizes[n];
- uint len = 1;
+ size_t sizes[n];
+ size_t len = 1;
- for (uns i=0; i<n; i++)
+ for (uint i=0; i<n; i++)
len += sizes[i] = strlen(a[i]);
if (sep && n)
len += n-1;
char *dest = mp_alloc_fast_noalign(p, len);
char *d = dest;
- for (uns i=0; i<n; i++)
+ for (uint i=0; i<n; i++)
{
if (sep && i)
*d++ = sep;
}
char *
-mp_str_from_mem(struct mempool *a, const void *mem, uint len)
+mp_str_from_mem(struct mempool *a, const void *mem, size_t len)
{
char *str = mp_alloc_noalign(a, len+1);
memcpy(str, mem, len);
#include <string.h>
#define MP_CHUNK_TAIL ALIGN_TO(sizeof(struct mempool_chunk), CPU_STRUCT_ALIGN)
-#define MP_SIZE_MAX (~0U - MP_CHUNK_TAIL - CPU_PAGE_SIZE)
+#define MP_SIZE_MAX (SIZE_MAX - MP_CHUNK_TAIL - CPU_PAGE_SIZE)
struct mempool_chunk {
#ifdef CONFIG_DEBUG
struct mempool *pool; // Can be useful when analysing coredump for memory leaks
#endif
struct mempool_chunk *next;
- uint size;
+ size_t size;
};
-static uint
-mp_align_size(uint size)
+static size_t
+mp_align_size(size_t size)
{
#ifdef CONFIG_UCW_POOL_IS_MMAP
return ALIGN_TO(size + MP_CHUNK_TAIL, CPU_PAGE_SIZE) - MP_CHUNK_TAIL;
}
void
-mp_init(struct mempool *pool, uint chunk_size)
+mp_init(struct mempool *pool, size_t chunk_size)
{
chunk_size = mp_align_size(MAX(sizeof(struct mempool), chunk_size));
*pool = (struct mempool) {
}
static void *
-mp_new_big_chunk(struct mempool *pool, uint size)
+mp_new_big_chunk(struct mempool *pool, size_t size)
{
struct mempool_chunk *chunk;
chunk = xmalloc(size + MP_CHUNK_TAIL) + size;
}
static void *
-mp_new_chunk(struct mempool *pool, uint size)
+mp_new_chunk(struct mempool *pool, size_t size)
{
#ifdef CONFIG_UCW_POOL_IS_MMAP
struct mempool_chunk *chunk;
}
struct mempool *
-mp_new(uint chunk_size)
+mp_new(size_t chunk_size)
{
chunk_size = mp_align_size(MAX(sizeof(struct mempool), chunk_size));
struct mempool_chunk *chunk = mp_new_chunk(NULL, chunk_size);
}
static void
- mp_stats_chain(struct mempool *pool, struct mempool_chunk *chunk, struct mempool_stats *stats, uns idx)
+ mp_stats_chain(struct mempool *pool, struct mempool_chunk *chunk, struct mempool_stats *stats, uint idx)
{
while (chunk)
{
}
void *
-mp_alloc_internal(struct mempool *pool, uint size)
+mp_alloc_internal(struct mempool *pool, size_t size)
{
struct mempool_chunk *chunk;
if (size <= pool->threshold)
else if (likely(size <= MP_SIZE_MAX))
{
pool->idx = 1;
- uint aligned = ALIGN_TO(size, CPU_STRUCT_ALIGN);
+ size_t aligned = ALIGN_TO(size, CPU_STRUCT_ALIGN);
chunk = mp_new_big_chunk(pool, aligned);
chunk->next = pool->state.last[1];
#ifdef CONFIG_DEBUG
return pool->last_big = (void *)chunk - aligned;
}
else
- die("Cannot allocate %u bytes from a mempool", size);
+ die("Cannot allocate %zu bytes from a mempool", size);
}
void *
-mp_alloc(struct mempool *pool, uint size)
+mp_alloc(struct mempool *pool, size_t size)
{
return mp_alloc_fast(pool, size);
}
void *
-mp_alloc_noalign(struct mempool *pool, uint size)
+mp_alloc_noalign(struct mempool *pool, size_t size)
{
return mp_alloc_fast_noalign(pool, size);
}
void *
-mp_alloc_zero(struct mempool *pool, uint size)
+mp_alloc_zero(struct mempool *pool, size_t size)
{
void *ptr = mp_alloc_fast(pool, size);
bzero(ptr, size);
}
void *
-mp_start_internal(struct mempool *pool, uint size)
+mp_start_internal(struct mempool *pool, size_t size)
{
void *ptr = mp_alloc_internal(pool, size);
pool->state.free[pool->idx] += size;
}
void *
-mp_start(struct mempool *pool, uint size)
+mp_start(struct mempool *pool, size_t size)
{
return mp_start_fast(pool, size);
}
void *
-mp_start_noalign(struct mempool *pool, uint size)
+mp_start_noalign(struct mempool *pool, size_t size)
{
return mp_start_fast_noalign(pool, size);
}
void *
-mp_grow_internal(struct mempool *pool, uint size)
+mp_grow_internal(struct mempool *pool, size_t size)
{
if (unlikely(size > MP_SIZE_MAX))
- die("Cannot allocate %u bytes of memory", size);
- uint avail = mp_avail(pool);
+ die("Cannot allocate %zu bytes of memory", size);
+ size_t avail = mp_avail(pool);
void *ptr = mp_ptr(pool);
if (pool->idx)
{
- uint amortized = likely(avail <= MP_SIZE_MAX / 2) ? avail * 2 : MP_SIZE_MAX;
+ size_t amortized = likely(avail <= MP_SIZE_MAX / 2) ? avail * 2 : MP_SIZE_MAX;
amortized = MAX(amortized, size);
amortized = ALIGN_TO(amortized, CPU_STRUCT_ALIGN);
struct mempool_chunk *chunk = pool->state.last[1], *next = chunk->next;
}
}
-uint
+size_t
mp_open(struct mempool *pool, void *ptr)
{
return mp_open_fast(pool, ptr);
}
void *
-mp_realloc(struct mempool *pool, void *ptr, uint size)
+mp_realloc(struct mempool *pool, void *ptr, size_t size)
{
return mp_realloc_fast(pool, ptr, size);
}
void *
-mp_realloc_zero(struct mempool *pool, void *ptr, uint size)
+mp_realloc_zero(struct mempool *pool, void *ptr, size_t size)
{
- uint old_size = mp_open_fast(pool, ptr);
+ size_t old_size = mp_open_fast(pool, ptr);
ptr = mp_grow(pool, size);
if (size > old_size)
bzero(ptr + old_size, size - old_size);
}
void *
-mp_spread_internal(struct mempool *pool, void *p, uint size)
+mp_spread_internal(struct mempool *pool, void *p, size_t size)
{
void *old = mp_ptr(pool);
void *new = mp_grow_internal(pool, p-old+size);
#include <time.h>
static void
- fill(byte *ptr, uns len, uns magic)
+ fill(byte *ptr, uint len, uint magic)
{
while (len--)
*ptr++ = (magic++ & 255);
}
static void
- check(byte *ptr, uns len, uns magic, uns align)
+ check(byte *ptr, uint len, uint magic, uint align)
{
ASSERT(!((uintptr_t)ptr & (align - 1)));
while (len--)
if (cf_getopt(argc, argv, CF_SHORT_OPTS, CF_NO_LONG_OPTS, NULL) >= 0 || argc != optind)
die("Invalid usage");
- uns max = 1000, n = 0, m = 0, can_realloc = 0;
+ uint max = 1000, n = 0, m = 0, can_realloc = 0;
void *ptr[max];
struct mempool_state *state[max];
- uns len[max], num[max], align[max];
+ uint len[max], num[max], align[max];
struct mempool *mp = mp_new(128), mp_static;
- for (uns i = 0; i < 5000; i++)
+ for (uint i = 0; i < 5000; i++)
{
- for (uns j = 0; j < n; j++)
+ for (uint j = 0; j < n; j++)
check(ptr[j], len[j], j, align[j]);
#if 0
DBG("free_small=%u free_big=%u idx=%u chunk_size=%u last_big=%p", mp->state.free[0], mp->state.free[1], mp->idx, mp->chunk_size, mp->last_big);
ASSERT(0);
grow:
{
- uns k = n - 1;
- for (uns i = random_max(4); i--; )
+ uint k = n - 1;
+ for (uint i = random_max(4); i--; )
{
- uns l = len[k];
+ uint l = len[k];
len[k] = random_max(0x2000);
DBG("grow(%u)", len[k]);
ptr[k] = mp_grow(mp, len[k]);
}
else if (can_realloc && n && (r -= 20) < 0)
{
- uns i = n - 1, l = len[i];
+ uint i = n - 1, l = len[i];
DBG("realloc(%p, %u)", ptr[i], len[i]);
ptr[i] = mp_realloc(mp, ptr[i], len[i] = random_max(0x2000));
DBG(" -> (%p, %u)", ptr[i], len[i]);
}
else if (m && (r -= 1) < 0)
{
- uns i = random_max(m);
+ uint i = random_max(m);
DBG("restore(%u)", i);
mp_restore(mp, state[i]);
n = num[m = i];
* You should use this one as an opaque handle only, the insides are internal.
**/
struct mempool_state {
- uint free[2];
+ size_t free[2];
void *last[2];
struct mempool_state *next;
};
struct ucw_allocator allocator;
struct mempool_state state;
void *unused, *last_big;
- uint chunk_size, threshold, idx;
+ size_t chunk_size, threshold;
+ uns idx;
u64 total_size;
};
struct mempool_stats { /** Mempool statistics. See @mp_stats(). **/
u64 total_size; /* Real allocated size in bytes */
u64 used_size; /* Estimated size allocated from mempool to application */
- uns chain_count[3]; /* Number of allocated chunks in small/big/unused chains */
+ uint chain_count[3]; /* Number of allocated chunks in small/big/unused chains */
u64 chain_size[3]; /* Size of allocated chunks in small/big/unused chains */
};
/**
* Initialize a given mempool structure.
- * @chunk_size must be in the interval `[1, UINT_MAX / 2]`.
+ * @chunk_size must be in the interval `[1, SIZE_MAX / 2]`.
* It will allocate memory by this large chunks and take
* memory to satisfy requests from them.
*
* Memory pools can be treated as <<trans:respools,resources>>, see <<trans:res_mempool()>>.
**/
-void mp_init(struct mempool *pool, uint chunk_size);
+void mp_init(struct mempool *pool, size_t chunk_size);
/**
* Allocate and initialize a new memory pool.
*
* Memory pools can be treated as <<trans:respools,resources>>, see <<trans:res_mempool()>>.
**/
-struct mempool *mp_new(uint chunk_size);
+struct mempool *mp_new(size_t chunk_size);
/**
* Cleanup mempool initialized by mp_init or mp_new.
***/
/* For internal use only, do not call directly */
-void *mp_alloc_internal(struct mempool *pool, uint size) LIKE_MALLOC;
+void *mp_alloc_internal(struct mempool *pool, size_t size) LIKE_MALLOC;
/**
* The function allocates new @size bytes on a given memory pool.
* `CPU_STRUCT_ALIGN` bytes and this condition remains true also
* after future reallocations.
**/
-void *mp_alloc(struct mempool *pool, uint size);
+void *mp_alloc(struct mempool *pool, size_t size);
/**
* The same as @mp_alloc(), but the result may be unaligned.
**/
-void *mp_alloc_noalign(struct mempool *pool, uint size);
+void *mp_alloc_noalign(struct mempool *pool, size_t size);
/**
* The same as @mp_alloc(), but fills the newly allocated memory with zeroes.
**/
-void *mp_alloc_zero(struct mempool *pool, uint size);
+void *mp_alloc_zero(struct mempool *pool, size_t size);
/**
* Inlined version of @mp_alloc().
**/
-static inline void *mp_alloc_fast(struct mempool *pool, uint size)
+static inline void *mp_alloc_fast(struct mempool *pool, size_t size)
{
- uint avail = pool->state.free[0] & ~(CPU_STRUCT_ALIGN - 1);
+ size_t avail = pool->state.free[0] & ~(size_t)(CPU_STRUCT_ALIGN - 1);
if (size <= avail)
{
pool->state.free[0] = avail - size;
/**
* Inlined version of @mp_alloc_noalign().
**/
-static inline void *mp_alloc_fast_noalign(struct mempool *pool, uint size)
+static inline void *mp_alloc_fast_noalign(struct mempool *pool, size_t size)
{
if (size <= pool->state.free[0])
{
***/
/* For internal use only, do not call directly */
-void *mp_start_internal(struct mempool *pool, uint size) LIKE_MALLOC;
-void *mp_grow_internal(struct mempool *pool, uint size);
-void *mp_spread_internal(struct mempool *pool, void *p, uint size);
+void *mp_start_internal(struct mempool *pool, size_t size) LIKE_MALLOC;
+void *mp_grow_internal(struct mempool *pool, size_t size);
+void *mp_spread_internal(struct mempool *pool, void *p, size_t size);
- static inline uns mp_idx(struct mempool *pool, void *ptr)
+ static inline uint mp_idx(struct mempool *pool, void *ptr)
{
return ptr == pool->last_big;
}
* Keep in mind that you can't make any other pool allocations
* before you "close" the growing buffer with @mp_end().
*/
-void *mp_start(struct mempool *pool, uint size);
-void *mp_start_noalign(struct mempool *pool, uint size);
+void *mp_start(struct mempool *pool, size_t size);
+void *mp_start_noalign(struct mempool *pool, size_t size);
/**
* Inlined version of @mp_start().
**/
-static inline void *mp_start_fast(struct mempool *pool, uint size)
+static inline void *mp_start_fast(struct mempool *pool, size_t size)
{
- uint avail = pool->state.free[0] & ~(CPU_STRUCT_ALIGN - 1);
+ size_t avail = pool->state.free[0] & ~(size_t)(CPU_STRUCT_ALIGN - 1);
if (size <= avail)
{
pool->idx = 0;
/**
* Inlined version of @mp_start_noalign().
**/
-static inline void *mp_start_fast_noalign(struct mempool *pool, uint size)
+static inline void *mp_start_fast_noalign(struct mempool *pool, size_t size)
{
if (size <= pool->state.free[0])
{
* Return the number of bytes available for extending the growing buffer.
* (Before a reallocation will be needed).
**/
-static inline uint mp_avail(struct mempool *pool)
+static inline size_t mp_avail(struct mempool *pool)
{
return pool->state.free[pool->idx];
}
* change its starting position. The content will be unchanged to the minimum
* of the old and new sizes; newly allocated memory will be uninitialized.
* Multiple calls to mp_grow() have amortized linear cost wrt. the maximum value of @size. */
-static inline void *mp_grow(struct mempool *pool, uint size)
+static inline void *mp_grow(struct mempool *pool, size_t size)
{
return (size <= mp_avail(pool)) ? mp_ptr(pool) : mp_grow_internal(pool, size);
}
* Ensure that there is at least @size bytes free after @p,
* if not, reallocate and adjust @p.
**/
-static inline void *mp_spread(struct mempool *pool, void *p, uint size)
+static inline void *mp_spread(struct mempool *pool, void *p, size_t size)
{
- return (((uint)((byte *)pool->state.last[pool->idx] - (byte *)p) >= size) ? p : mp_spread_internal(pool, p, size));
+ return (((size_t)((byte *)pool->state.last[pool->idx] - (byte *)p) >= size) ? p : mp_spread_internal(pool, p, size));
}
/**
* the last byte in the buffer, returns a pointer after the last byte
* of the new (possibly reallocated) buffer.
**/
- static inline char *mp_append_char(struct mempool *pool, char *p, uns c)
+ static inline char *mp_append_char(struct mempool *pool, char *p, uint c)
{
p = mp_spread(pool, p, 1);
*p++ = c;
* the last byte in the buffer, returns a pointer after the last byte
* of the new (possibly reallocated) buffer.
**/
-static inline void *mp_append_block(struct mempool *pool, void *p, const void *block, uint size)
+static inline void *mp_append_block(struct mempool *pool, void *p, const void *block, size_t size)
{
char *q = mp_spread(pool, p, size);
memcpy(q, block, size);
/**
* Return size in bytes of the last allocated memory block (with @mp_alloc() or @mp_end()).
**/
-static inline uint mp_size(struct mempool *pool, void *ptr)
+static inline size_t mp_size(struct mempool *pool, void *ptr)
{
- uns idx = mp_idx(pool, ptr);
+ uint idx = mp_idx(pool, ptr);
return ((byte *)pool->state.last[idx] - (byte *)ptr) - pool->state.free[idx];
}
* for growing and return its size in bytes. The contents and the start pointer
* remain unchanged. Do not forget to call @mp_end() to close it.
**/
-uint mp_open(struct mempool *pool, void *ptr);
+size_t mp_open(struct mempool *pool, void *ptr);
/**
* Inlined version of @mp_open().
**/
-static inline uint mp_open_fast(struct mempool *pool, void *ptr)
+static inline size_t mp_open_fast(struct mempool *pool, void *ptr)
{
pool->idx = mp_idx(pool, ptr);
- uint size = ((byte *)pool->state.last[pool->idx] - (byte *)ptr) - pool->state.free[pool->idx];
+ size_t size = ((byte *)pool->state.last[pool->idx] - (byte *)ptr) - pool->state.free[pool->idx];
pool->state.free[pool->idx] += size;
return size;
}
* to the new @size. Behavior is similar to @mp_grow(), but the resulting
* block is closed.
**/
-void *mp_realloc(struct mempool *pool, void *ptr, uint size);
+void *mp_realloc(struct mempool *pool, void *ptr, size_t size);
/**
* The same as @mp_realloc(), but fills the additional bytes (if any) with zeroes.
**/
-void *mp_realloc_zero(struct mempool *pool, void *ptr, uint size);
+void *mp_realloc_zero(struct mempool *pool, void *ptr, size_t size);
/**
* Inlined version of @mp_realloc().
**/
-static inline void *mp_realloc_fast(struct mempool *pool, void *ptr, uint size)
+static inline void *mp_realloc_fast(struct mempool *pool, void *ptr, size_t size)
{
mp_open_fast(pool, ptr);
ptr = mp_grow(pool, size);
***/
char *mp_strdup(struct mempool *, const char *) LIKE_MALLOC; /** Makes a copy of a string on a mempool. Returns NULL for NULL string. **/
-void *mp_memdup(struct mempool *, const void *, uint) LIKE_MALLOC; /** Makes a copy of a memory block on a mempool. **/
+void *mp_memdup(struct mempool *, const void *, size_t) LIKE_MALLOC; /** Makes a copy of a memory block on a mempool. **/
/**
* Concatenates all passed strings. The last parameter must be NULL.
* This will concatenate two strings:
* @p is the mempool to provide memory, @a is array of strings and @n
* tells how many there is of them.
**/
- char *mp_strjoin(struct mempool *p, char **a, uns n, uns sep) LIKE_MALLOC;
+ char *mp_strjoin(struct mempool *p, char **a, uint n, uint sep) LIKE_MALLOC;
/**
* Convert memory block to a string. Makes a copy of the given memory block
* in the mempool @p, adding an extra terminating zero byte at the end.
**/
-char *mp_str_from_mem(struct mempool *p, const void *mem, uint len) LIKE_MALLOC;
+char *mp_str_from_mem(struct mempool *p, const void *mem, size_t len) LIKE_MALLOC;
/***
#include <ucw/string.h>
#include <ucw/chartype.h>
- static uns
- hex_make(uns x)
+ static uint
+ hex_make(uint x)
{
return (x < 10) ? (x + '0') : (x - 10 + 'a');
}
void
-mem_to_hex(char *dest, const byte *src, uint bytes, uint flags)
+mem_to_hex(char *dest, const byte *src, size_t bytes, uns flags)
{
- uns sep = flags & 0xff;
+ uint sep = flags & 0xff;
while (bytes--)
{
*dest = 0;
}
- static uns
- hex_parse(uns c)
+ static uint
+ hex_parse(uint c)
{
c = Cupcase(c);
c -= '0';
}
const char *
-hex_to_mem(byte *dest, const char *src, uint max_bytes, uint flags)
+hex_to_mem(byte *dest, const char *src, size_t max_bytes, uns flags)
{
- uns sep = flags & 0xff;
+ uint sep = flags & 0xff;
while (max_bytes-- && Cxdigit(src[0]) && Cxdigit(src[1]))
{
*dest++ = (hex_parse(src[0]) << 4) | hex_parse(src[1]);
#include <ucw/string.h>
#ifdef CONFIG_DARWIN
-uint
-strnlen(const char *str, uint n)
+size_t
+strnlen(const char *str, size_t n)
{
const char *end = str + n;
const char *c;
#endif
char *
- str_format_flags(char *dest, const char *fmt, uns flags)
+ str_format_flags(char *dest, const char *fmt, uint flags)
{
char *start = dest;
- for (uns i=0; fmt[i]; i++)
+ for (uint i=0; fmt[i]; i++)
{
if (flags & (1 << i))
*dest++ = fmt[i];
return start;
}
-uint
-str_count_char(const char *str, uint chr)
+size_t
+str_count_char(const char *str, uns chr)
{
const byte *s = str;
- uint i = 0;
+ size_t i = 0;
while (*s)
if (*s++ == chr)
i++;
/* string.c */
#ifdef CONFIG_DARWIN
-uint strnlen(const char *str, uint n); // NOAPI
+size_t strnlen(const char *str, size_t n); // NOAPI
#endif
/**
* Format a set of flag bits. When the i-th bit of @flags is 1,
* set the i-th character of @dest to @fmt[i], otherwise to '-'.
**/
- char *str_format_flags(char *dest, const char *fmt, uns flags);
+ char *str_format_flags(char *dest, const char *fmt, uint flags);
/** Counts occurrences of @chr in @str. **/
-uint str_count_char(const char *str, uint chr);
+size_t str_count_char(const char *str, uns chr);
/* str-esc.c */
* When there are more than @max fields in @str, the first @max fields
* are processed and -1 is returned.
**/
- int str_sepsplit(char *str, uns sep, char **rec, uns max);
+ int str_sepsplit(char *str, uint sep, char **rec, uint max);
/**
* Split @str to words separated by white-space characters. The spaces
* Fields surrounded by double quotes are also recognized. They can contain
* spaces, but no mechanism for escaping embedded quotes is defined.
**/
- int str_wordsplit(char *str, char **rec, uns max);
+ int str_wordsplit(char *str, char **rec, uint max);
/* str-(i)match.c: Matching of shell patterns */
* not be separated), possibly OR-ed with `MEM_TO_HEX_UPCASE` when upper-case
* characters should be used.
**/
-void mem_to_hex(char *dest, const byte *src, uint bytes, uint flags);
+void mem_to_hex(char *dest, const byte *src, size_t bytes, uns flags);
/**
* An inverse function to @mem_to_hex(). Takes a hexdump of at most @max_bytes
* bytes and stores the bytes to a buffer starting at @dest. Returns a pointer
* at the first character after the dump.
**/
-const char *hex_to_mem(byte *dest, const char *src, uint max_bytes, uint flags);
+const char *hex_to_mem(byte *dest, const char *src, size_t max_bytes, uns flags);
// Bottom 8 bits of flags are an optional separator of bytes, the rest is:
#define MEM_TO_HEX_UPCASE 0x100
* - "/" is a prefix,
* - "" is a prefix.
**/
- int str_hier_prefix(const char *str, const char *prefix, uns sep);
- int str_hier_suffix(const char *str, const char *suffix, uns sep); /** Like @str_hier_prefix(), but for suffixes. **/
+ int str_hier_prefix(const char *str, const char *prefix, uint sep);
+ int str_hier_suffix(const char *str, const char *suffix, uint sep); /** Like @str_hier_prefix(), but for suffixes. **/
#endif
#include <ucw/lib.h>
#include <ucw/unicode.h>
-uint
+size_t
utf8_strlen(const byte *str)
{
- uint len = 0;
+ size_t len = 0;
while (*str)
{
UTF8_SKIP(str);
return len;
}
-uint
-utf8_strnlen(const byte *str, uint n)
+size_t
+utf8_strnlen(const byte *str, size_t n)
{
- uint len = 0;
+ size_t len = 0;
const byte *end = str + n;
while (str < end)
{
#undef F
};
- uns func = ~0U;
+ uint func = ~0U;
if (argc > 1)
- for (uns i = 0; i < ARRAY_SIZE(names); i++)
+ for (uint i = 0; i < ARRAY_SIZE(names); i++)
if (!strcasecmp(names[i], argv[1]))
func = i;
if (!~func)
if (func < FUNC_UTF8_PUT)
{
byte *p = buf, *q = buf, *last;
- uns u;
+ uint u;
bzero(buf, sizeof(buf));
while (scanf("%x", &u) == 1)
*q++ = u;
}
else
{
- uns u, i=0;
+ uint u, i=0;
while (scanf("%x", &u) == 1)
{
byte *p = buf, *q = buf;
* Encode a value from the range `[0, 0xFFFF]`
* (basic multilingual plane); up to 3 bytes needed (RFC2279).
**/
- static inline byte *utf8_put(byte *p, uns u)
+ static inline byte *utf8_put(byte *p, uint u)
{
if (u < 0x80)
*p++ = u;
* Encode a value from the range `[0, 0x7FFFFFFF]`;
* (superset of Unicode 4.0) up to 6 bytes needed (RFC2279).
**/
- static inline byte *utf8_32_put(byte *p, uns u)
+ static inline byte *utf8_32_put(byte *p, uint u)
{
if (u < 0x80)
*p++ = u;
* Decode a value from the range `[0, 0xFFFF]` (basic multilingual plane)
* or return @repl if the encoding has been corrupted.
**/
- static inline byte *utf8_get_repl(const byte *p, uns *uu, uns repl)
+ static inline byte *utf8_get_repl(const byte *p, uint *uu, uint repl)
{
- uns u = *p++;
+ uint u = *p++;
if (u < 0x80)
;
else if (unlikely(u < 0xc0))
* Decode a value from the range `[0, 0x7FFFFFFF]`
* or return @repl if the encoding has been corrupted.
**/
- static inline byte *utf8_32_get_repl(const byte *p, uns *uu, uns repl)
+ static inline byte *utf8_32_get_repl(const byte *p, uint *uu, uint repl)
{
- uns u = *p++;
+ uint u = *p++;
if (u < 0x80)
;
else if (unlikely(u < 0xc0))
* Decode a value from the range `[0, 0xFFFF]` (basic multilingual plane)
* or return `UNI_REPLACEMENT` if the encoding has been corrupted.
**/
- static inline byte *utf8_get(const byte *p, uns *uu)
+ static inline byte *utf8_get(const byte *p, uint *uu)
{
return utf8_get_repl(p, uu, UNI_REPLACEMENT);
}
* Decode a value from the range `[0, 0x7FFFFFFF]`
* or return `UNI_REPLACEMENT` if the encoding has been corrupted.
**/
- static inline byte *utf8_32_get(const byte *p, uns *uu)
+ static inline byte *utf8_32_get(const byte *p, uint *uu)
{
return utf8_32_get_repl(p, uu, UNI_REPLACEMENT);
}
#define UTF8_SKIP(p) do { \
- uns c = *p++; \
+ uint c = *p++; \
if (c >= 0xc0) \
while (c & 0x40 && *p >= 0x80 && *p < 0xc0) \
p++, c <<= 1; \
/**
* Return the number of bytes needed to encode a given value from the range `[0, 0x7FFFFFFF]` to UTF-8.
**/
- static inline uns utf8_space(uns u)
+ static inline uint utf8_space(uint u)
{
if (u < 0x80)
return 1;
/**
* Compute the length of a single UTF-8 character from its first byte. The encoding must be valid.
**/
- static inline uns utf8_encoding_len(uns c)
+ static inline uint utf8_encoding_len(uint c)
{
if (c < 0x80)
return 1;
* Encode an UTF-16LE character from the range `[0, 0xD7FF]` or `[0xE000,0x11FFFF]`;
* up to 4 bytes needed.
**/
- static inline void *utf16_le_put(void *p, uns u)
+ static inline void *utf16_le_put(void *p, uint u)
{
if (u < 0xd800 || (u < 0x10000 && u >= 0xe000))
{
* Encode a UTF-16BE character from the range `[0, 0xD7FF]` or `[0xE000,0x11FFFF]`;
* up to 4 bytes needed.
**/
- static inline void *utf16_be_put(void *p, uns u)
+ static inline void *utf16_be_put(void *p, uint u)
{
if (u < 0xd800 || (u < 0x10000 && u >= 0xe000))
{
* Decode a UTF-16LE character from the range `[0, 0xD7FF]` or `[0xE000,11FFFF]`
* or return @repl if the encoding has been corrupted.
**/
- static inline void *utf16_le_get_repl(const void *p, uns *uu, uns repl)
+ static inline void *utf16_le_get_repl(const void *p, uint *uu, uint repl)
{
- uns u = get_u16_le(p), x, y;
+ uint u = get_u16_le(p), x, y;
x = u - 0xd800;
if (x < 0x800)
if (x < 0x400 && (y = get_u16_le(p + 2) - 0xdc00) < 0x400)
* Decode a UTF-16BE character from the range `[0, 0xD7FF]` or `[0xE000,11FFFF]`
* or return @repl if the encoding has been corrupted.
**/
- static inline void *utf16_be_get_repl(const void *p, uns *uu, uns repl)
+ static inline void *utf16_be_get_repl(const void *p, uint *uu, uint repl)
{
- uns u = get_u16_be(p), x, y;
+ uint u = get_u16_be(p), x, y;
x = u - 0xd800;
if (x < 0x800)
if (x < 0x400 && (y = get_u16_be(p + 2) - 0xdc00) < 0x400)
* Decode a UTF-16LE character from the range `[0, 0xD7FF]` or `[0xE000,11FFFF]`
* or return `UNI_REPLACEMENT` if the encoding has been corrupted.
**/
- static inline void *utf16_le_get(const void *p, uns *uu)
+ static inline void *utf16_le_get(const void *p, uint *uu)
{
return utf16_le_get_repl(p, uu, UNI_REPLACEMENT);
}
* Decode a UTF-16BE character from the range `[0, 0xD7FF]` or `[0xE000,11FFFF]`
* or return `UNI_REPLACEMENT` if the encoding has been corrupted.
**/
- static inline void *utf16_be_get(const void *p, uns *uu)
+ static inline void *utf16_be_get(const void *p, uint *uu)
{
return utf16_be_get_repl(p, uu, UNI_REPLACEMENT);
}
* character is a surrogate, ASCII or Latin-1 control character different from the tab,
* or if it lies outside the basic plane. In all other cases, it acts as an identity.
**/
- static inline uns unicode_sanitize_char(uns u)
+ static inline uint unicode_sanitize_char(uint u)
{
if (u >= 0x10000 || // We don't accept anything outside the basic plane
u >= 0xd800 && u < 0xf900 || // neither we do surrogates
* Count the number of Unicode characters in a zero-terminated UTF-8 string.
* Returned value for corrupted encoding is undefined, but is never greater than strlen().
**/
-uint utf8_strlen(const byte *str);
+size_t utf8_strlen(const byte *str);
/**
* Same as @utf8_strlen(), but returns at most @n characters.
**/
-uint utf8_strnlen(const byte *str, uint n);
+size_t utf8_strnlen(const byte *str, size_t n);
#endif