.\" .\" Copyright 2013 Samy Al Bahra. .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" .Dd July 26, 2013. .Dt ck_sequence 3 .Sh NAME .Nm ck_sequence_init , .Nm ck_sequence_read_begin , .Nm ck_sequence_read_retry , .Nm ck_sequence_write_begin , .Nm ck_sequence_write_end .Nd sequence locks .Sh LIBRARY Concurrency Kit (libck, \-lck) .Sh SYNOPSIS .In ck_sequence.h .Pp .Dv ck_sequence_t seqlock = CK_SEQUENCE_INITIALIZER; .Pp .Ft void .Fn ck_sequence_init "ck_sequence_t *sq" .Ft unsigned int .Fn ck_sequence_read_begin "const ck_sequence_t *sq" .Ft bool .Fn ck_sequence_read_retry "const ck_sequence_t *sq" "unsigned int version" .Ft void .Fn ck_sequence_write_begin "ck_sequence_t *sq" .Ft void .Fn ck_sequence_write_end "ck_sequence_t *sq" .Sh DESCRIPTION It is recommended to use ck_sequence when a small amount of data that cannot be accessed atomically has to be synchronized with readers in a fashion that does not block any writer. Readers are able to execute their read-side critical sections without any atomic operations. A ck_sequence_t must be initialized before use. It may be initialized using either a static initializer (CK_SEQUENCE_INITIALIZER) or using .Fn ck_sequence_init . Before readers attempt to read data that may be concurrently modified they must first save the return value of .Fn ck_sequence_read_begin . While or after a reader has completed copying the data associated with a ck_sequence_t it must pass the earlier return value of .Fn ck_sequence_read_begin to .Fn "ck_sequence_read_retry". If .Fn ck_sequence_read_retry returns true then the copy of data may be inconsistent and the read process must be retried. Writers must rely on their own synchronization primitives. Once a writer has entered its respective critical section, it must call .Fn ck_sequence_write_begin to signal intent to update the data protected by the ck_sequence_t. Before the writer leaves its critical section it must execute .Fn ck_sequence_write_end to indicate that the updates have left respective objects in a consistent state. .Sh EXAMPLE .Bd -literal -offset indent #include #include static struct example { int a; int b; int c; } global; static ck_sequence_t seqlock = CK_SEQUENCE_INITIALIZER; void reader(void) { struct example copy; unsigned int version; /* * Attempt a read of the data structure. If the structure * has been modified between ck_sequence_read_begin and * ck_sequence_read_retry then attempt another read since * the data may be in an inconsistent state. */ do { version = ck_sequence_read_begin(&seqlock); copy = global; } while (ck_sequence_read_retry(&seqlock, version)); /* * The previous may also be expressed using CK_SEQUENCE_READ. * Generally recommend to only use ck_sequence_read_retry * if you would like to detect a conflicting write at some * higher granularity. */ CK_SEQUENCE_READ(&seqlock, &version) { copy = global; } return; } void writer(void) { for (;;) { ck_sequence_write_begin(&seqlock); global.a = rand(); global.b = global.a + global.b; global.c = global.b + global.c; ck_sequence_write_end(&seqlock); } return; } .Ed .Sh SEE ALSO .Xr ck_brlock 3 , .Xr ck_bytelock 3 , .Xr ck_rwlock 3 .Pp Additional information available at http://concurrencykit.org/