1*72445076SMariusz Zaborski.\" 2*72445076SMariusz Zaborski.\" Copyright (C) 2019 Mariusz Zaborski <oshogbo@FreeBSD.org> 3*72445076SMariusz Zaborski.\" 4*72445076SMariusz Zaborski.\" Redistribution and use in source and binary forms, with or without 5*72445076SMariusz Zaborski.\" modification, are permitted provided that the following conditions 6*72445076SMariusz Zaborski.\" are met: 7*72445076SMariusz Zaborski.\" 1. Redistributions of source code must retain the above copyright 8*72445076SMariusz Zaborski.\" notice(s), this list of conditions and the following disclaimer as 9*72445076SMariusz Zaborski.\" the first lines of this file unmodified other than the possible 10*72445076SMariusz Zaborski.\" addition of one or more copyright notices. 11*72445076SMariusz Zaborski.\" 2. Redistributions in binary form must reproduce the above copyright 12*72445076SMariusz Zaborski.\" notice(s), this list of conditions and the following disclaimer in the 13*72445076SMariusz Zaborski.\" documentation and/or other materials provided with the distribution. 14*72445076SMariusz Zaborski.\" 15*72445076SMariusz Zaborski.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY 16*72445076SMariusz Zaborski.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17*72445076SMariusz Zaborski.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18*72445076SMariusz Zaborski.\" DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY 19*72445076SMariusz Zaborski.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20*72445076SMariusz Zaborski.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21*72445076SMariusz Zaborski.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22*72445076SMariusz Zaborski.\" CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23*72445076SMariusz Zaborski.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24*72445076SMariusz Zaborski.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 25*72445076SMariusz Zaborski.\" DAMAGE. 26*72445076SMariusz Zaborski.\" 27*72445076SMariusz Zaborski.\" $FreeBSD$ 28*72445076SMariusz Zaborski.\" 29*72445076SMariusz Zaborski.Dd July 29, 2019 30*72445076SMariusz Zaborski.Dt SEQC 9 31*72445076SMariusz Zaborski.Os 32*72445076SMariusz Zaborski.Sh NAME 33*72445076SMariusz Zaborski.Nm seqc_consistent , 34*72445076SMariusz Zaborski.Nm seqc_read , 35*72445076SMariusz Zaborski.Nm seqc_write_begin , 36*72445076SMariusz Zaborski.Nm seqc_write_end 37*72445076SMariusz Zaborski.Nd "lockless read algorithm" 38*72445076SMariusz Zaborski.Sh SYNOPSIS 39*72445076SMariusz Zaborski.In sys/seqc.h 40*72445076SMariusz Zaborski.Ft void 41*72445076SMariusz Zaborski.Fn seqc_write_begin "seqc_t *seqcp" 42*72445076SMariusz Zaborski.Ft void 43*72445076SMariusz Zaborski.Fn seqc_write_end "seqc_t *seqcp" 44*72445076SMariusz Zaborski.Ft seqc_t 45*72445076SMariusz Zaborski.Fn seqc_read "seqc_t *seqcp" 46*72445076SMariusz Zaborski.Ft seqc_t 47*72445076SMariusz Zaborski.Fn seqc_consistent "const seqc_t *seqcp" "seqc_t oldseqc" 48*72445076SMariusz Zaborski.Sh DESCRIPTION 49*72445076SMariusz ZaborskiThe 50*72445076SMariusz Zaborski.Nm seqc 51*72445076SMariusz Zaborskiallows zero or more readers and zero or one writer to concurrently access 52*72445076SMariusz Zaborskian object, providing a consistent snapshot of the object for readers. 53*72445076SMariusz ZaborskiNo mutual exclusion between readers and writers is required, 54*72445076SMariusz Zaborskibut readers may be starved indefinitely by writers. 55*72445076SMariusz Zaborski.Pp 56*72445076SMariusz ZaborskiThe functions 57*72445076SMariusz Zaborski.Fn seqc_write_begin 58*72445076SMariusz Zaborskiand 59*72445076SMariusz Zaborski.Fn seqc_write_end 60*72445076SMariusz Zaborskiare used to create a transaction for writer, and notify the readers that the 61*72445076SMariusz Zaborskiobject will be modified. 62*72445076SMariusz Zaborski.Pp 63*72445076SMariusz ZaborskiThe 64*72445076SMariusz Zaborski.Fn seqc_read 65*72445076SMariusz Zaborskifunction returns the current sequence number. 66*72445076SMariusz ZaborskiIf a writer has started a transaction, this function will spin until the 67*72445076SMariusz Zaborskitransaction has ended. 68*72445076SMariusz Zaborski.Pp 69*72445076SMariusz ZaborskiThe 70*72445076SMariusz Zaborski.Fn seqc_consistent 71*72445076SMariusz Zaborskifunction compares the sequence number with a previously fetched value. 72*72445076SMariusz ZaborskiThe 73*72445076SMariusz Zaborski.Fa oldseqc 74*72445076SMariusz Zaborskivariable should contain a sequence number from the beginning of read 75*72445076SMariusz Zaborskitransaction. 76*72445076SMariusz Zaborski.Pp 77*72445076SMariusz ZaborskiThe reader at the end of a transaction checks if the sequence number has 78*72445076SMariusz Zaborskichanged. 79*72445076SMariusz ZaborskiIf the sequence number didn't change the object wasn't modified, and fetched 80*72445076SMariusz Zaborskivariables are valid. 81*72445076SMariusz ZaborskiIf the sequence number changed the object was modified and the fetch should be 82*72445076SMariusz Zaborskirepeated. 83*72445076SMariusz ZaborskiIn case when sequence number is odd the object change is in progress and the 84*72445076SMariusz Zaborskireader will wait until the write will the sequence number will become even. 85*72445076SMariusz Zaborski.Sh EXAMPLES 86*72445076SMariusz ZaborskiThe following example for a writer changees the 87*72445076SMariusz Zaborski.Va var1 88*72445076SMariusz Zaborskiand 89*72445076SMariusz Zaborski.Va var2 90*72445076SMariusz Zaborskivariables in the 91*72445076SMariusz Zaborski.Va obj 92*72445076SMariusz Zaborskistructure: 93*72445076SMariusz Zaborski.Bd -literal 94*72445076SMariusz Zaborskilock_exclusive(&obj->lock); 95*72445076SMariusz Zaborskiseqc_write_begin(&obj->seqc); 96*72445076SMariusz Zaborskiobj->var1 = 1; 97*72445076SMariusz Zaborskiobj->var2 = 2; 98*72445076SMariusz Zaborskiseqc_write_end(&obj->seqc); 99*72445076SMariusz Zaborskiunlock_exclusive(&obj->lock); 100*72445076SMariusz Zaborski.Ed 101*72445076SMariusz ZaborskiThe following example for a reader reads the 102*72445076SMariusz Zaborski.Va var1 103*72445076SMariusz Zaborskiand 104*72445076SMariusz Zaborski.Va var2 105*72445076SMariusz Zaborskivariables from the 106*72445076SMariusz Zaborski.Va obj 107*72445076SMariusz Zaborskistructure. 108*72445076SMariusz ZaborskiIn the case where the sequence number was changed it restarts the whole process. 109*72445076SMariusz Zaborski.Bd -literal 110*72445076SMariusz Zaborskiint var1, var2; 111*72445076SMariusz Zaborskiseqc_t seqc; 112*72445076SMariusz Zaborski 113*72445076SMariusz Zaborskifor (;;) { 114*72445076SMariusz Zaborski seqc = seqc_read(&obj->seqc); 115*72445076SMariusz Zaborski var1 = obj->var1; 116*72445076SMariusz Zaborski var2 = obj->var2; 117*72445076SMariusz Zaborski if (seqc_consistent(&obj->seqc, seqc)) 118*72445076SMariusz Zaborski break; 119*72445076SMariusz Zaborski} 120*72445076SMariusz Zaborski.Ed 121*72445076SMariusz Zaborski.Sh AUTHORS 122*72445076SMariusz ZaborskiThe 123*72445076SMariusz Zaborski.Nm seqc 124*72445076SMariusz Zaborskifunctions was implemented by 125*72445076SMariusz Zaborski.An Mateusz Guzik Aq Mt mjg@FreeBSD.org . 126*72445076SMariusz ZaborskiThis manual page was written by 127*72445076SMariusz Zaborski.An Mariusz Zaborski Aq Mt oshogbo@FreeBSD.org . 128*72445076SMariusz Zaborski.Sh CAVEATS 129*72445076SMariusz ZaborskiThere is no guarantee of progress for readers. 130*72445076SMariusz ZaborskiIn case when there are a lot of writers the reader can be starved. 131*72445076SMariusz ZaborskiThis concern may be solved by returning error after a few attempts. 132*72445076SMariusz Zaborski.Pp 133*72445076SMariusz ZaborskiTheoretically if reading takes a very long time, and when there are many writers 134*72445076SMariusz Zaborskithe counter may overflow and wrap around to the same value. 135*72445076SMariusz ZaborskiIn that case the reader will not notice that the object was changed. 136*72445076SMariusz ZaborskiGiven that this needs 4 billion transactional writes across a single contended 137*72445076SMariusz Zaborskireader, it is unlikely to ever happen. 138*72445076SMariusz ZaborskiThis could be avoided by extending the interface to allow 64-bit counters. 139