epoch.9 (6e36248f79fd89a469fec1dc76723fcf1ea382ef) epoch.9 (70398c2f86e2fbc2120b4a11d9ec9284a6a395f5)
1.\"
2.\" Copyright (C) 2018 Matthew Macy <mmacy@FreeBSD.org>.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice(s), this list of conditions and the following disclaimer as

--- 35 unchanged lines hidden (view full) ---

44.In sys/param.h
45.In sys/proc.h
46.In sys/epoch.h
47.Ft epoch_t
48.Fn epoch_alloc "int flags"
49.Ft void
50.Fn epoch_enter "epoch_t epoch"
51.Ft void
1.\"
2.\" Copyright (C) 2018 Matthew Macy <mmacy@FreeBSD.org>.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice(s), this list of conditions and the following disclaimer as

--- 35 unchanged lines hidden (view full) ---

44.In sys/param.h
45.In sys/proc.h
46.In sys/epoch.h
47.Ft epoch_t
48.Fn epoch_alloc "int flags"
49.Ft void
50.Fn epoch_enter "epoch_t epoch"
51.Ft void
52.Fn epoch_enter_critical "epoch_t epoch"
52.Fn epoch_enter_preempt "epoch_t epoch"
53.Ft void
54.Fn epoch_exit "epoch_t epoch"
55.Ft void
53.Ft void
54.Fn epoch_exit "epoch_t epoch"
55.Ft void
56.Fn epoch_exit_critical "epoch_t epoch"
56.Fn epoch_exit_preempt "epoch_t epoch"
57.Ft void
58.Fn epoch_wait "epoch_t epoch"
59.Ft void
57.Ft void
58.Fn epoch_wait "epoch_t epoch"
59.Ft void
60.Fn epoch_wait_critical "epoch_t epoch"
60.Fn epoch_wait_preempt "epoch_t epoch"
61.Ft void
62.Fn epoch_call "epoch_t epoch" "epoch_context_t ctx" "void (*callback) (epoch_context_t)"
63.Ft int
64.Fn in_epoch "void"
65.Sh DESCRIPTION
66Epochs are used to guarantee liveness and immutability of data by
67deferring reclamation and mutation until a grace period has elapsed.
68Epochs do not have any lock ordering issues. Entering and leaving
69an epoch section will never block.
70.Pp
71Epochs are allocated with
72.Fn epoch_alloc
73and freed with
74.Fn epoch_free .
75The flags passed to epoch_alloc determine whether preemption is
61.Ft void
62.Fn epoch_call "epoch_t epoch" "epoch_context_t ctx" "void (*callback) (epoch_context_t)"
63.Ft int
64.Fn in_epoch "void"
65.Sh DESCRIPTION
66Epochs are used to guarantee liveness and immutability of data by
67deferring reclamation and mutation until a grace period has elapsed.
68Epochs do not have any lock ordering issues. Entering and leaving
69an epoch section will never block.
70.Pp
71Epochs are allocated with
72.Fn epoch_alloc
73and freed with
74.Fn epoch_free .
75The flags passed to epoch_alloc determine whether preemption is
76allowed during a section (the default) or not, as specified by
77EPOCH_CRITICAL.
76allowed during a section or not (the dafult), as specified by
77EPOCH_PREEMPT.
78Threads indicate the start of an epoch critical section by calling
79.Fn epoch_enter .
80The end of a critical section is indicated by calling
81.Fn epoch_exit .
78Threads indicate the start of an epoch critical section by calling
79.Fn epoch_enter .
80The end of a critical section is indicated by calling
81.Fn epoch_exit .
82The _critical variants can be used around code in which it is safe
83to have preemption disable.
82The _preempt variants can be used around code which requires preemption.
84A thread can wait until a grace period has elapsed
85since any threads have entered
86the epoch by calling
83A thread can wait until a grace period has elapsed
84since any threads have entered
85the epoch by calling
87.Fn epoch_wait .
88The use of a EPOCH_CRITICAL epoch type allows one to use
89.Fn epoch_wait_critical
86.Fn epoch_wait
87or
88.Fn epoch_wait_preempt ,
89depending on the epoch_type.
90The use of a default epoch type allows one to use
91.Fn epoch_wait
90which is guaranteed to have much shorter completion times since
91we know that none of the threads in an epoch section will be preempted
92before completing its section.
93If the thread can't sleep or is otherwise in a performance sensitive
94path it can ensure that a grace period has elapsed by calling
95.Fn epoch_call
96with a callback with any work that needs to wait for an epoch to elapse.
97Only non-sleepable locks can be acquired during a section protected by
92which is guaranteed to have much shorter completion times since
93we know that none of the threads in an epoch section will be preempted
94before completing its section.
95If the thread can't sleep or is otherwise in a performance sensitive
96path it can ensure that a grace period has elapsed by calling
97.Fn epoch_call
98with a callback with any work that needs to wait for an epoch to elapse.
99Only non-sleepable locks can be acquired during a section protected by
98.Fn epoch_enter
100.Fn epoch_enter_preempt
99and
101and
100.Fn epoch_exit .
102.Fn epoch_exit_preempt .
101INVARIANTS can assert that a thread is in an epoch by using
102.Fn in_epoch .
103.Pp
103INVARIANTS can assert that a thread is in an epoch by using
104.Fn in_epoch .
105.Pp
104The epoch API currently does not support sleeping in epoch sections.
105A caller cannot do epoch_enter recursively on different epochs. A
106The epoch API currently does not support sleeping in epoch_preempt sections.
107A caller cannot do epoch_enter recursively on different preemptible epochs. A
106caller should never call
107.Fn epoch_wait
108in the middle of an epoch section as this will lead to a deadlock.
109.Pp
110Note that epochs are not a straight replacement for read locks. Callers
111must use safe list and tailq traversal routines in an epoch (see ck_queue).
112When modifying a list referenced from an epoch section safe removal
113routines must be used and the caller can no longer modify a list entry
114in place. An item to be modified must be handled with copy on write
115and frees must be deferred until after a grace period has elapsed.
108caller should never call
109.Fn epoch_wait
110in the middle of an epoch section as this will lead to a deadlock.
111.Pp
112Note that epochs are not a straight replacement for read locks. Callers
113must use safe list and tailq traversal routines in an epoch (see ck_queue).
114When modifying a list referenced from an epoch section safe removal
115routines must be used and the caller can no longer modify a list entry
116in place. An item to be modified must be handled with copy on write
117and frees must be deferred until after a grace period has elapsed.
116
117.Sh RETURN VALUES
118.Fn in_epoch
119will return 1 if curthread is in an epoch, 0 otherwise.
118.Sh RETURN VALUES
119.Fn in_epoch
120will return 1 if curthread is in an epoch, 0 otherwise.
121.Sh CAVEATS
122One must be cautious when using
123.Fn epoch_wait_preempt
124threads are pinned during epoch sections so if a thread in a section is then
125preempted by a higher priority compute bound thread on that CPU it can be
126prevented from leaving the section. Thus the wait time for the waiter is
127potentially unbounded.
120.Sh EXAMPLES
121Async free example:
122
123Thread 1:
124.Bd -literal
125int
126in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_laddr *laddr,
127 struct ucred *cred)

--- 56 unchanged lines hidden ---
128.Sh EXAMPLES
129Async free example:
130
131Thread 1:
132.Bd -literal
133int
134in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_laddr *laddr,
135 struct ucred *cred)

--- 56 unchanged lines hidden ---