From c4b28acd90b1dc5370f6d565f5f95a2144e151c5 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Fri, 29 Jan 2010 00:28:21 +0100 Subject: [PATCH] Add a 'guard' size parameter to ringbuffer construction, remove hardcoded The size of ringbuffer wraparound pages at each end of the data was hardcoded to 1 page. This remove this restriction and lets one pass explicit sizes for this areas. This also adds a (guard=N) option parsed from the NOBUG_LOG env var. --- src/nobug.c | 2 +- src/nobug.h | 6 +++--- src/nobug_env.c | 10 +++++++++- src/nobug_rbdump.c | 3 ++- src/nobug_ringbuffer.c | 46 ++++++++++++++++++++++++++++------------------ 5 files changed, 43 insertions(+), 24 deletions(-) diff --git a/src/nobug.c b/src/nobug.c index 4057d42..0284468 100644 --- a/src/nobug.c +++ b/src/nobug.c @@ -99,7 +99,7 @@ nobug_init (const struct nobug_context context) /* we initialize a minimal ringbuffer, if not already done */ if (!nobug_default_ringbuffer.start) - nobug_ringbuffer_init (&nobug_default_ringbuffer, 4096, NULL, NOBUG_RINGBUFFER_DEFAULT); + nobug_ringbuffer_init (&nobug_default_ringbuffer, 4096, 4096, NULL, NOBUG_RINGBUFFER_DEFAULT); /* initialize the always-on flag*/ nobug_flag_NOBUG_ON.ringbuffer_target = &nobug_default_ringbuffer; diff --git a/src/nobug.h b/src/nobug.h index 6ac2d86..7455a0a 100644 --- a/src/nobug.h +++ b/src/nobug.h @@ -2030,7 +2030,7 @@ struct nobug_ringbuffer char* pos; char* start; size_t size; - size_t maxmsg; + size_t guard; char name[256]; }; @@ -2048,10 +2048,10 @@ enum nobug_ringbuffer_flags struct nobug_ringbuffer* nobug_ringbuffer_init (struct nobug_ringbuffer* self, size_t size, - const char * name, int flags); + size_t guard, const char * name, int flags); struct nobug_ringbuffer* -nobug_ringbuffer_new (size_t size, const char * name, int flags); +nobug_ringbuffer_new (size_t size, size_t guard, const char * name, int flags); struct nobug_ringbuffer* nobug_ringbuffer_destroy (struct nobug_ringbuffer* self); diff --git a/src/nobug_env.c b/src/nobug_env.c index 7a9766d..14cb27b 100644 --- a/src/nobug_env.c +++ b/src/nobug_env.c @@ -201,6 +201,7 @@ nobug_env_parse_flag (const char* env, struct nobug_flag* flag, int default_targ char name[256]; *name = '\0'; size_t size = 4096; + size_t guard = 4096; int flags = 0; switch (target) @@ -222,6 +223,13 @@ nobug_env_parse_flag (const char* env, struct nobug_flag* flag, int default_targ continue; } + /* (guard=N) */ + if ((s = nobug_env_parse_size_option (&env, "guard", &guard))) + { + given |= s; + continue; + } + /* (append) (temp) (keep) */ if ((s = nobug_env_parse_flag_option (&env, "append", &flags, NOBUG_RINGBUFFER_APPEND))) @@ -251,7 +259,7 @@ nobug_env_parse_flag (const char* env, struct nobug_flag* flag, int default_targ /* create new ringbuffer for flag */ if (flag->ringbuffer_target != &nobug_default_ringbuffer) nobug_ringbuffer_delete (flag->ringbuffer_target); - flag->ringbuffer_target = nobug_ringbuffer_new (size, name, flags); + flag->ringbuffer_target = nobug_ringbuffer_new (size, guard, name, flags); } break; case NOBUG_TARGET_CONSOLE: diff --git a/src/nobug_rbdump.c b/src/nobug_rbdump.c index 1671fb1..45d2920 100644 --- a/src/nobug_rbdump.c +++ b/src/nobug_rbdump.c @@ -65,7 +65,8 @@ main(int argc, char* argv[]) struct nobug_ringbuffer rb; - if (!nobug_ringbuffer_init (&rb, filestat.st_size, argv[1], NOBUG_RINGBUFFER_KEEP|NOBUG_RINGBUFFER_APPEND)) + /* using the file size for the guard too is quite excessive but the only way to be 100% sure any ringbuffer can be read */ + if (!nobug_ringbuffer_init (&rb, filestat.st_size, filestat.st_size, argv[1], NOBUG_RINGBUFFER_KEEP|NOBUG_RINGBUFFER_APPEND)) { fprintf (stderr, "Error opening ringbuffer %s\n", argv[1]); return 3; diff --git a/src/nobug_ringbuffer.c b/src/nobug_ringbuffer.c index e30de18..b051fc7 100644 --- a/src/nobug_ringbuffer.c +++ b/src/nobug_ringbuffer.c @@ -27,8 +27,6 @@ #define NOBUG_LIBNOBUG_C #include "nobug.h" -#define NOBUG_RINGBUFFER_MAX_MSG 4094 - #include "llist.h" #if NOBUG_USE_PTHREAD @@ -68,13 +66,19 @@ LLIST_AUTO(nobug_ringbuffer_registry); //ringbuffer + struct nobug_ringbuffer* -nobug_ringbuffer_init (struct nobug_ringbuffer* self, size_t size, const char * name, int flags) +nobug_ringbuffer_init (struct nobug_ringbuffer* self, size_t size, size_t guard, const char * name, int flags) { size_t pagesz = sysconf (_SC_PAGESIZE); - size = (size + pagesz-1) & ~(pagesz-1); - self->maxmsg = (NOBUG_RINGBUFFER_MAX_MSG+2 + pagesz-1) & ~(pagesz-1); + /* align size and guard on page boundaries, minimum is 1 page */ + size = self->size = (size?size:pagesz + pagesz-1) & ~(pagesz-1); + guard = self->guard = (guard?guard:pagesz + pagesz-1) & ~(pagesz-1); + + /* there is no point in having guards biggier than size */ + if (guard > size) + guard = size; self->name[255] = '\0'; if (!name) @@ -118,32 +122,33 @@ nobug_ringbuffer_init (struct nobug_ringbuffer* self, size_t size, const char * size, strerror(errno)); exit (EXIT_FAILURE); } - self->size = size; /* get contigous address range */ - char * start = mmap (0, size+2*self->maxmsg, PROT_NONE, MAP_SHARED|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0); + char * start = mmap (0, size+2*self->guard, PROT_NONE, MAP_SHARED|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0); if (!start) { fprintf(stderr, "nobug_ringbuffer: Failed to reserve %zd bytes of address space: %s\n", - size+2*self->maxmsg, strerror(errno)); + size+2*self->guard, strerror(errno)); exit (EXIT_FAILURE); } /* map the backing file */ - self->start = mmap (start+self->maxmsg, size, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_SHARED, fd, 0); + self->start = mmap (start+self->guard, size, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_SHARED, fd, 0); if (!self->start) { fprintf(stderr, "nobug_ringbuffer: Failed to mmap backing file, %s\n", strerror(errno)); exit (EXIT_FAILURE); } + /* map beginning after the end */ - if (!mmap (start+self->maxmsg+size, self->maxmsg, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_SHARED, fd, 0)) + if (!mmap (start+self->guard+size, self->guard, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_SHARED, fd, 0)) { fprintf(stderr, "nobug_ringbuffer: Failed to mmap trailing guard page, %s\n", strerror(errno)); exit (EXIT_FAILURE); } + /* map end before beginning */ - if (!mmap (start, self->maxmsg, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_SHARED, fd, size-self->maxmsg)) + if (!mmap (start, self->guard, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_SHARED, fd, size-self->guard)) { fprintf(stderr, "nobug_ringbuffer: Failed to mmap leading guard page, %s\n", strerror(errno)); exit (EXIT_FAILURE); @@ -183,12 +188,12 @@ nobug_ringbuffer_init (struct nobug_ringbuffer* self, size_t size, const char * struct nobug_ringbuffer* -nobug_ringbuffer_new (size_t size, const char * name, int flags) +nobug_ringbuffer_new (size_t size, size_t guard, const char * name, int flags) { struct nobug_ringbuffer* self = malloc (sizeof (struct nobug_ringbuffer)); if (!self) return NULL; - return nobug_ringbuffer_init (self, size, name, flags); + return nobug_ringbuffer_init (self, guard, size, name, flags); } @@ -205,7 +210,7 @@ nobug_ringbuffer_destroy (struct nobug_ringbuffer* self) if (self->name[0]) unlink(self->name); - munmap(self->start-self->maxmsg, self->size + 2 * self->maxmsg); + munmap(self->start-self->guard, self->size + 2 * self->guard); return self; } @@ -242,7 +247,8 @@ nobug_ringbuffer_allsync (void) int nobug_ringbuffer_vprintf (struct nobug_ringbuffer* self, const char* fmt, va_list ap) { - int written = vsnprintf (self->pos + 1, self->maxmsg-2, fmt, ap); + int written = vsnprintf (self->pos + 1, self->guard-2, fmt, ap); + self->pos += (written + 1); if (self->pos > self->start+self->size) @@ -288,7 +294,7 @@ nobug_ringbuffer_extend (struct nobug_ringbuffer* self, size_t newsize, const ch if (prev >= self->start+self->size) prev -= self->size; - if (prev+newsize+2 > self->start + self->size + self->maxmsg) + if (prev+newsize+2 > self->start + self->size + self->guard) return 0; if (fill) @@ -321,6 +327,7 @@ nobug_ringbuffer_prev (struct nobug_ringbuffer* self, char* pos) return pos+1; } + char* nobug_ringbuffer_next (struct nobug_ringbuffer* self, char* pos) { @@ -338,6 +345,7 @@ nobug_ringbuffer_next (struct nobug_ringbuffer* self, char* pos) return pos; } + int nobug_ringbuffer_save (struct nobug_ringbuffer* self, FILE* out) { @@ -360,9 +368,9 @@ int nobug_ringbuffer_load (struct nobug_ringbuffer* self, FILE* in) { int ret = 0; - char buf[NOBUG_RINGBUFFER_MAX_MSG]; + char buf[self->guard]; - while (fgets(buf, self->maxmsg, in)) + while (fgets(buf, self->guard, in)) { size_t l = strlen(buf); if (buf[l-1] == '\n') @@ -372,12 +380,14 @@ nobug_ringbuffer_load (struct nobug_ringbuffer* self, FILE* in) return ret; } + char* nobug_ringbuffer_pos (struct nobug_ringbuffer* self) { return self->pos+1; } + void nobug_ringbuffer_pop (struct nobug_ringbuffer* self) { -- 2.11.4.GIT