3423e217d064c1081001d2f3f83dd3d66f1e0312
[sliver-openvswitch.git] / lib / seq.h
1 /*
2  * Copyright (c) 2013 Nicira, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef SEQ_H
18 #define SEQ_H 1
19
20 /* Thread-safe, pollable sequence number.
21  *
22  *
23  * Background
24  * ==========
25  *
26  * It is sometimes desirable to take an action whenever an object changes.
27  * Suppose we associate a sequence number with an object and increment the
28  * sequence number whenver we change the object.  An observer can then record
29  * the sequence number it sees.  Later on, if the current sequence number
30  * differs from the one it saw last, then the observer knows to examine the
31  * object for changes.
32  *
33  * Code that wants to run when a sequence number changes is challenging to
34  * implement in a multithreaded environment.  A naive implementation, that
35  * simply checks whether the sequence number changed and, if so, calls
36  * poll_immediate_wake(), will fail when another thread increments the sequence
37  * number after the check (including during poll_block()).
38  *
39  * struct seq is a solution.  It implements a sequence number along with enough
40  * internal infrastructure so that a thread waiting on a particular value will
41  * wake up if the sequence number changes, or even if the "struct seq" is
42  * destroyed.
43  *
44  *
45  * Usage
46  * =====
47  *
48  * The object that includes a sequence number should use seq_create() and
49  * seq_destroy() at creation and destruction, and seq_change() whenever the
50  * object's observable state changes.
51  *
52  * An observer may seq_read() to read the current sequence number and
53  * seq_wait() to cause poll_block() to wake up when the sequence number changes
54  * from a specified value.
55  *
56  * To avoid races, observers should use seq_read() to check for changes,
57  * process any changes, and then use seq_wait() to wait for a change from the
58  * previously read value.  That is, a correct usage looks something like this:
59  *
60  *    new_seq = seq_read(seq);
61  *    if (new_seq != last_seq) {
62  *        ...process changes...
63  *        last_seq = new_seq;
64  *    }
65  *    seq_wait(seq, new_seq);
66  *    poll_block();
67  *
68  *
69  * Thread-safety
70  * =============
71  *
72  * Fully thread safe.
73  */
74
75 #include <stdint.h>
76
77 /* For implementation of an object with a sequence number attached. */
78 struct seq *seq_create(void);
79 void seq_destroy(struct seq *);
80 void seq_change(struct seq *);
81
82 /* For observers. */
83 uint64_t seq_read(const struct seq *);
84 void seq_wait(const struct seq *, uint64_t value);
85
86 /* For poll_block() internal use. */
87 void seq_woke(void);
88
89 #endif /* seq.h */