From: Martin Mares Date: Wed, 13 Sep 2006 19:38:05 +0000 (+0200) Subject: Atomic fastbufs: the first sketch of the interface. X-Git-Tag: holmes-import~512^2~7 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=9dc6f017d0b8c992d2df15a51cf96fc431260df3;p=libucw.git Atomic fastbufs: the first sketch of the interface. --- diff --git a/lib/Makefile b/lib/Makefile index 2a554870..775c7de6 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -15,7 +15,7 @@ LIBUCW_MODS= \ ipaccess \ profile \ fastbuf ff-binary ff-string ff-printf ff-utf8 \ - fb-file carefulio fb-mem fb-temp fb-mmap fb-limfd fb-buffer fb-grow \ + fb-file carefulio fb-mem fb-temp fb-mmap fb-limfd fb-buffer fb-grow fb-atomic \ str_ctype str_upper str_lower unicode-utf8 stkstring \ wildmatch wordsplit ctmatch patimatch patmatch regex \ prime primetable random timer randomkey \ diff --git a/lib/fastbuf.h b/lib/fastbuf.h index 6dbacce5..2d1c1eb3 100644 --- a/lib/fastbuf.h +++ b/lib/fastbuf.h @@ -118,6 +118,11 @@ struct fastbuf *fbgrow_create(unsigned basic_size); void fbgrow_reset(struct fastbuf *b); /* Reset stream and prepare for writing */ void fbgrow_rewind(struct fastbuf *b); /* Prepare for reading */ +/* FastO with atomic writes for multi-threaded programs */ + +struct fastbuf *fbatomic_create(byte *name, struct fastbuf *master, uns bufsize, int record_len); +void fbatomic_checkpoint(struct fastbuf *b); + /* Configuring stream parameters */ int bconfig(struct fastbuf *f, uns type, int data); diff --git a/lib/fb-atomic.c b/lib/fb-atomic.c new file mode 100644 index 00000000..29e7c303 --- /dev/null +++ b/lib/fb-atomic.c @@ -0,0 +1,50 @@ +/* + * UCW Library -- Atomic Buffered Write to Files + * + * (c) 2006 Martin Mares + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. + */ + +/* + * This fastbuf backend is intended for cases where several threads + * of a single program append records to a single file and while the + * record can mix in an arbitrary way, the bytes inside a single + * record must remain uninterrupted. + * + * In case of files with fixed record size, we just allocate the + * buffer to hold a whole number of records and take advantage + * of the atomicity of the write() system call. + * + * With variable-sized records, we need another solution: when + * writing a record, we keep the fastbuf in a locked state, which + * prevents buffer flushing (and if the buffer becomes full, we extend it), + * and we wait for an explicit commit operation which write()s the buffer + * if the free space in the buffer falls below the expected maximum record + * length. + * + * fbatomic_create() is called with the following parameters: + * name - name of the file to open + * master - fbatomic for the master thread or NULL if it's the first open + * bufsize - initial buffer size + * record_len - record length for fixed-size records; + * or -(expected maximum record length) for variable-sized ones. + */ + +#include "lib/lib.h" +#include "lib/fastbuf.h" +#include "lib/lfs.h" + +#include +#include +#include + +struct fb_atomic { + struct fastbuf fb; + int fd; /* File descriptor */ + uns locked; + uns expected_max_len; + byte *expected_max_bptr; +}; +#define FB_ATOMIC(f) ((struct fb_atomic *)(f)->is_fastbuf)