xref: /freebsd/share/man/man9/seqc.9 (revision 724450761630cc0b3d8991ec2de00a8ceb507384)
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