Modernize doc using Markdown
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Mon, 5 May 2014 18:59:11 +0000 (14:59 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 6 May 2014 11:52:50 +0000 (07:52 -0400)
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
README.md
doc/Makefile.am
doc/cds-api.md [new file with mode: 0644]
doc/cds-api.txt [deleted file]
doc/rcu-api.md [new file with mode: 0644]
doc/rcu-api.txt [deleted file]
doc/uatomic-api.md [new file with mode: 0644]
doc/uatomic-api.txt [deleted file]
urcu-call-rcu.h

index b33095cb71774d13f31d5ef02df4d67159fbe741..f6b290fbc4edca213b1d83dc7368581dd9e0aed9 100644 (file)
--- a/README.md
+++ b/README.md
@@ -115,13 +115,13 @@ API
 See the relevant API documentation files in `doc/`. The APIs provided by
 Userspace RCU are, by prefix:
 
-  - `rcu_`: Read-Copy Update (see [`doc/rcu-api.txt`](doc/rcu-api.txt))
+  - `rcu_`: Read-Copy Update (see [`doc/rcu-api.md`](doc/rcu-api.md))
   - `cmm_`: Concurrent Memory Model
   - `caa_`: Concurrent Architecture Abstraction
   - `cds_`: Concurrent Data Structures
-    (see [`doc/cds-api.txt`](doc/cds-api.txt))
+    (see [`doc/cds-api.md`](doc/cds-api.md))
   - `uatomic_`: Userspace Atomic
-    (see [`doc/uatomic-api.txt`](doc/uatomic-api.txt))
+    (see [`doc/uatomic-api.md`](doc/uatomic-api.md))
 
 
 Quick start guide
@@ -262,7 +262,7 @@ Its API is currently experimental. It may change in future library releases.
     grace periods.  A number of additional functions are provided
     to manage the helper threads used by `call_rcu()`, but reasonable
     defaults are used if these additional functions are not invoked.
-    See [`doc/rcu-api.txt`](doc/rcu-api.txt) in userspace-rcu documentation
+    See [`doc/rcu-api.md`](doc/rcu-api.md) in userspace-rcu documentation
     for more details.
 
 
@@ -396,4 +396,4 @@ Contacts
 --------
 
 You can contact the maintainers on the following mailing list:
-`lttng-dev@lists.lttng.org`.
\ No newline at end of file
+`lttng-dev@lists.lttng.org`.
index d98f16ba8f3e7bb80a6a6c63cbe3e02095d0a699..ce1774c986e8ad904fed133c9341fa09c7d3b8fc 100644 (file)
@@ -1,3 +1,3 @@
 SUBDIRS = examples
 
-dist_doc_DATA = rcu-api.txt cds-api.txt uatomic-api.txt
+dist_doc_DATA = rcu-api.md cds-api.md uatomic-api.md
diff --git a/doc/cds-api.md b/doc/cds-api.md
new file mode 100644 (file)
index 0000000..49a3c7c
--- /dev/null
@@ -0,0 +1,84 @@
+Userspace RCU Concurrent Data Structures (CDS) API
+==================================================
+
+by Mathieu Desnoyers and Paul E. McKenney
+
+This document describes briefly the data structures contained with the
+userspace RCU library.
+
+
+Data structure files
+--------------------
+
+### `urcu/list.h`
+
+Doubly-linked list, which requires mutual exclusion on
+updates and reads.
+
+
+### `urcu/rculist.h`
+
+Doubly-linked list, which requires mutual exclusion on
+updates, allows RCU read traversals.
+
+
+### `urcu/hlist.h`
+
+Doubly-linked list, with single pointer list head. Requires
+mutual exclusion on updates and reads. Useful for implementing hash tables.
+Downside over `list.h`: lookup of tail in O(n).
+
+
+### `urcu/rcuhlist.h`
+
+Doubly-linked list, with single pointer list head.
+Requires mutual exclusion on updates, allows RCU read traversals. Useful
+for implementing hash tables. Downside over rculist.h: lookup of tail in O(n).
+
+
+### `urcu/wfstack.h`
+
+Stack with wait-free push and wait-free pop_all. Both
+blocking and non-blocking pop and traversal operations are provided. This
+stack does _not_ specifically rely on RCU. Various synchronization techniques
+can be used to deal with pop ABA. Those are detailed in the API.
+
+
+### `urcu/wfcqueue.h`
+
+Concurrent queue with wait-free enqueue. Both blocking and
+non-blocking dequeue, splice (move all elements from one queue
+to another), and traversal operations are provided.
+
+This queue does _not_ specifically rely on RCU. Mutual exclusion
+is used to protect dequeue, splice (from source queue) and
+traversal (see API for details).
+
+  - Note: deprecates `urcu/wfqueue.h`.
+
+
+### `urcu/lfstack.h`
+
+Stack with lock-free push, lock-free pop, wait-free pop_all,
+wait-free traversal. Various synchronization techniques can be
+used to deal with pop ABA. Those are detailed in the API.
+This stack does _not_ specifically rely on RCU.
+
+  - Note: deprecates `urcu/rculfstack.h`.
+
+
+### `urcu/rculfqueue.h`
+
+RCU queue with lock-free enqueue, lock-free dequeue.
+This queue relies on RCU for existence guarantees.
+
+
+### `urcu/rculfhash.h`
+
+Lock-Free Resizable RCU Hash Table. RCU used to provide
+existance guarantees. Provides scalable updates, and scalable
+RCU read-side lookups and traversals. Unique and duplicate keys
+are supported. Provides "uniquify add" and "replace add"
+operations, along with associated read-side traversal uniqueness
+guarantees. Automatic hash table resize based on number of
+elements is supported. See the API for more details.
diff --git a/doc/cds-api.txt b/doc/cds-api.txt
deleted file mode 100644 (file)
index 8896e20..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-Userspace RCU Concurrent Data Structures (CDS) API
-by Mathieu Desnoyers and Paul E. McKenney
-
-
-This document describes briefly the data structures contained with the
-userspace RCU library.
-
-urcu/list.h:
-
-       Doubly-linked list, which requires mutual exclusion on updates
-       and reads.
-
-urcu/rculist.h:
-
-       Doubly-linked list, which requires mutual exclusion on updates,
-       allows RCU read traversals.
-       
-urcu/hlist.h:
-
-       Doubly-linked list, with single pointer list head. Requires
-       mutual exclusion on updates and reads. Useful for implementing
-       hash tables. Downside over list.h: lookup of tail in O(n).
-
-urcu/rcuhlist.h:
-
-       Doubly-linked list, with single pointer list head. Requires
-       mutual exclusion on updates, allows RCU read traversals. Useful
-       for implementing hash tables. Downside over rculist.h: lookup of
-       tail in O(n).
-
-urcu/wfstack.h:
-
-       Stack with wait-free push and wait-free pop_all. Both blocking
-       and non-blocking pop and traversal operations are provided.
-       This stack does _not_ specifically rely on RCU.
-       Various synchronization techniques can be used to deal with
-       pop ABA. Those are detailed in the API.
-
-urcu/wfcqueue.h:
-
-       Concurrent queue with wait-free enqueue. Both blocking and
-       non-blocking dequeue, splice (move all elements from one queue
-       to another), and traversal operations are provided.
-       This queue does _not_ specifically rely on RCU. Mutual exclusion
-       is used to protect dequeue, splice (from source queue) and
-       traversal (see API for details).
-       (note: deprecates urcu/wfqueue.h)
-
-urcu/lfstack.h:
-
-       Stack with lock-free push, lock-free pop, wait-free pop_all,
-       wait-free traversal. Various synchronization techniques can be
-       used to deal with pop ABA. Those are detailed in the API.
-       This stack does _not_ specifically rely on RCU.
-       (note: deprecates urcu/rculfstack.h)
-
-urcu/rculfqueue.h:
-
-       RCU queue with lock-free enqueue, lock-free dequeue.
-       This queue relies on RCU for existence guarantees.
-
-urcu/rculfhash.h:
-
-       Lock-Free Resizable RCU Hash Table. RCU used to provide
-       existance guarantees. Provides scalable updates, and scalable
-       RCU read-side lookups and traversals. Unique and duplicate keys
-       are supported. Provides "uniquify add" and "replace add"
-       operations, along with associated read-side traversal uniqueness
-       guarantees. Automatic hash table resize based on number of
-       elements is supported. See the API for more details.
diff --git a/doc/rcu-api.md b/doc/rcu-api.md
new file mode 100644 (file)
index 0000000..ea316d1
--- /dev/null
@@ -0,0 +1,240 @@
+Userspace RCU API
+=================
+
+by Mathieu Desnoyers and Paul E. McKenney
+
+
+API
+---
+
+```c
+void rcu_init(void);
+```
+
+This must be called before any of the following functions
+are invoked.
+
+
+```c
+void rcu_read_lock(void);
+```
+
+Begin an RCU read-side critical section. These critical
+sections may be nested.
+
+
+```c
+void rcu_read_unlock(void);
+```
+
+End an RCU read-side critical section.
+
+
+```c
+void rcu_register_thread(void);
+```
+
+Each thread must invoke this function before its first call to
+`rcu_read_lock()`. Threads that never call `rcu_read_lock()` need
+not invoke this function. In addition, `rcu-bp` ("bullet proof"
+RCU) does not require any thread to invoke `rcu_register_thread()`.
+
+
+```c
+void rcu_unregister_thread(void);
+```
+
+Each thread that invokes `rcu_register_thread()` must invoke
+`rcu_unregister_thread()` before `invoking pthread_exit()`
+or before returning from its top-level function.
+
+
+```c
+void synchronize_rcu(void);
+```
+
+Wait until every pre-existing RCU read-side critical section
+has completed. Note that this primitive will not necessarily
+wait for RCU read-side critical sections that have not yet
+started: this is not a reader-writer lock. The duration
+actually waited is called an RCU grace period.
+
+
+```c
+void call_rcu(struct rcu_head *head,
+              void (*func)(struct rcu_head *head));
+```
+
+Registers the callback indicated by "head". This means
+that `func` will be invoked after the end of a future
+RCU grace period. The `rcu_head` structure referenced
+by `head` will normally be a field in a larger RCU-protected
+structure. A typical implementation of `func` is as
+follows:
+
+```c
+void func(struct rcu_head *head)
+{
+    struct foo *p = container_of(head, struct foo, rcu);
+
+    free(p);
+}
+```
+
+This RCU callback function can be registered as follows
+given a pointer `p` to the enclosing structure:
+
+```c
+call_rcu(&p->rcu, func);
+```
+
+`call_rcu` should be called from registered RCU read-side threads.
+For the QSBR flavor, the caller should be online.
+
+
+```c
+void rcu_barrier(void);
+```
+
+Wait for all `call_rcu()` work initiated prior to `rcu_barrier()` by
+_any_ thread on the system to have completed before `rcu_barrier()`
+returns. `rcu_barrier()` should never be called from a `call_rcu()`
+thread. This function can be used, for instance, to ensure that
+all memory reclaim involving a shared object has completed
+before allowing `dlclose()` of this shared object to complete.
+
+
+```c
+struct call_rcu_data *create_call_rcu_data(unsigned long flags,
+                                           int cpu_affinity);
+```
+
+Returns a handle that can be passed to the following
+primitives. The `flags` argument can be zero, or can be
+`URCU_CALL_RCU_RT` if the worker threads associated with the
+new helper thread are to get real-time response. The argument
+`cpu_affinity` specifies a CPU on which the `call_rcu` thread should
+be affined to. It is ignored if negative.
+
+
+```c
+void call_rcu_data_free(struct call_rcu_data *crdp);
+```
+
+Terminates a `call_rcu()` helper thread and frees its associated
+data. The caller must have ensured that this thread is no longer
+in use, for example, by passing `NULL` to `set_thread_call_rcu_data()`
+and `set_cpu_call_rcu_data()` as required.
+
+
+```c
+struct call_rcu_data *get_default_call_rcu_data(void);
+```
+
+Returns the handle for the default `call_rcu()` helper thread.
+Creates it if necessary.
+
+
+```c
+struct call_rcu_data *get_cpu_call_rcu_data(int cpu);
+```
+
+Returns the handle for the current CPU's `call_rcu()` helper
+thread, or `NULL` if the current CPU has no helper thread
+currently assigned. The call to this function and use of the
+returned `call_rcu_data` should be protected by RCU read-side
+lock.
+
+
+```c
+struct call_rcu_data *get_thread_call_rcu_data(void);
+```
+
+Returns the handle for the current thread's hard-assigned
+`call_rcu()` helper thread, or `NULL` if the current thread is
+instead using a per-CPU or the default helper thread.
+
+
+```c
+struct call_rcu_data *get_call_rcu_data(void);
+```
+
+Returns the handle for the current thread's `call_rcu()` helper
+thread, which is either, in increasing order of preference:
+per-thread hard-assigned helper thread, per-CPU helper thread,
+or default helper thread. `get_call_rcu_data` should be called
+from registered RCU read-side threads. For the QSBR flavor, the
+caller should be online.
+
+
+```c
+pthread_t get_call_rcu_thread(struct call_rcu_data *crdp);
+```
+
+Returns the helper thread's pthread identifier linked to a call
+rcu helper thread data.
+
+
+```c
+void set_thread_call_rcu_data(struct call_rcu_data *crdp);
+```
+
+Sets the current thread's hard-assigned `call_rcu()` helper to the
+handle specified by `crdp`. Note that `crdp` can be `NULL` to
+disassociate this thread from its helper. Once a thread is
+disassociated from its helper, further `call_rcu()` invocations
+use the current CPU's helper if there is one and the default
+helper otherwise.
+
+
+```c
+int set_cpu_call_rcu_data(int cpu, struct call_rcu_data *crdp);
+```
+
+Sets the specified CPU's `call_rcu()` helper to the handle
+specified by `crdp`. Again, `crdp` can be `NULL` to disassociate
+this CPU from its helper thread. Once a CPU has been
+disassociated from its helper, further `call_rcu()` invocations
+that would otherwise have used this CPU's helper will instead
+use the default helper.
+
+The caller must wait for a grace-period to pass between return from
+`set_cpu_call_rcu_data()` and call to `call_rcu_data_free()` passing the
+previous call rcu data as argument.
+
+
+```c
+int create_all_cpu_call_rcu_data(unsigned long flags);
+```
+
+Creates a separate `call_rcu()` helper thread for each CPU.
+After this primitive is invoked, the global default `call_rcu()`
+helper thread will not be called.
+
+The `set_thread_call_rcu_data()`, `set_cpu_call_rcu_data()`, and
+`create_all_cpu_call_rcu_data()` functions may be combined to set up
+pretty much any desired association between worker and `call_rcu()`
+helper threads. If a given executable calls only `call_rcu()`,
+then that executable will have only the single global default
+`call_rcu()` helper thread. This will suffice in most cases.
+
+
+```c
+void free_all_cpu_call_rcu_data(void);
+```
+
+Clean up all the per-CPU `call_rcu` threads. Should be paired with
+`create_all_cpu_call_rcu_data()` to perform teardown. Note that
+this function invokes `synchronize_rcu()` internally, so the
+caller should be careful not to hold mutexes (or mutexes within a
+dependency chain) that are also taken within a RCU read-side
+critical section, or in a section where QSBR threads are online.
+
+
+```c
+void call_rcu_after_fork_child(void);
+```
+
+Should be used as `pthread_atfork()` handler for programs using
+`call_rcu` and performing `fork()` or `clone()` without a following
+`exec()`.
diff --git a/doc/rcu-api.txt b/doc/rcu-api.txt
deleted file mode 100644 (file)
index b647316..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-Userspace RCU API
-by Mathieu Desnoyers and Paul E. McKenney
-
-
-void rcu_init(void);
-
-       This must be called before any of the following functions
-       are invoked.
-
-void rcu_read_lock(void);
-
-       Begin an RCU read-side critical section.  These critical
-       sections may be nested.
-
-void rcu_read_unlock(void);
-
-       End an RCU read-side critical section.
-
-void rcu_register_thread(void);
-
-       Each thread must invoke this function before its first call to
-       rcu_read_lock().  Threads that never call rcu_read_lock() need
-       not invoke this function.  In addition, rcu-bp ("bullet proof"
-       RCU) does not require any thread to invoke rcu_register_thread().
-
-void rcu_unregister_thread(void);
-
-       Each thread that invokes rcu_register_thread() must invoke
-       rcu_unregister_thread() before invoking pthread_exit()
-       or before returning from its top-level function.
-
-void synchronize_rcu(void);
-
-       Wait until every pre-existing RCU read-side critical section
-       has completed.  Note that this primitive will not necessarily
-       wait for RCU read-side critical sections that have not yet
-       started: this is not a reader-writer lock.  The duration
-       actually waited is called an RCU grace period.
-
-void call_rcu(struct rcu_head *head,
-             void (*func)(struct rcu_head *head));
-
-       Registers the callback indicated by "head".  This means
-       that "func" will be invoked after the end of a future
-       RCU grace period.  The rcu_head structure referenced
-       by "head" will normally be a field in a larger RCU-protected
-       structure.  A typical implementation of "func" is as
-       follows:
-
-               void func(struct rcu_head *head)
-               {
-                       struct foo *p = container_of(head, struct foo, rcu);
-
-                       free(p);
-               }
-
-       This RCU callback function can be registered as follows
-       given a pointer "p" to the enclosing structure:
-
-               call_rcu(&p->rcu, func);
-
-       call_rcu should be called from registered RCU read-side threads.
-       For the QSBR flavor, the caller should be online.
-
-void rcu_barrier(void);
-
-       Wait for all call_rcu() work initiated prior to rcu_barrier() by
-       _any_ thread on the system to have completed before rcu_barrier()
-       returns. rcu_barrier() should never be called from a call_rcu()
-       thread. This function can be used, for instance, to ensure that
-       all memory reclaim involving a shared object has completed
-       before allowing dlclose() of this shared object to complete.
-
-struct call_rcu_data *create_call_rcu_data(unsigned long flags,
-                                          int cpu_affinity);
-
-       Returns a handle that can be passed to the following
-       primitives.  The "flags" argument can be zero, or can be
-       URCU_CALL_RCU_RT if the worker threads associated with the
-       new helper thread are to get real-time response. The argument
-       "cpu_affinity" specifies a cpu on which the call_rcu thread should
-       be affined to. It is ignored if negative.
-
-void call_rcu_data_free(struct call_rcu_data *crdp);
-
-       Terminates a call_rcu() helper thread and frees its associated
-       data.  The caller must have ensured that this thread is no longer
-       in use, for example, by passing NULL to set_thread_call_rcu_data()
-       and set_cpu_call_rcu_data() as required.
-
-struct call_rcu_data *get_default_call_rcu_data(void);
-
-       Returns the handle for the default call_rcu() helper thread.
-       Creates it if necessary.
-
-struct call_rcu_data *get_cpu_call_rcu_data(int cpu);
-
-       Returns the handle for the current cpu's call_rcu() helper
-       thread, or NULL if the current CPU has no helper thread
-       currently assigned. The call to this function and use of the
-       returned call_rcu_data should be protected by RCU read-side
-       lock.
-
-struct call_rcu_data *get_thread_call_rcu_data(void);
-
-       Returns the handle for the current thread's hard-assigned
-       call_rcu() helper thread, or NULL if the current thread is
-       instead using a per-CPU or the default helper thread.
-
-struct call_rcu_data *get_call_rcu_data(void);
-
-       Returns the handle for the current thread's call_rcu() helper
-       thread, which is either, in increasing order of preference:
-       per-thread hard-assigned helper thread, per-cpu helper thread,
-       or default helper thread. get_call_rcu_data should be called
-       from registered RCU read-side threads. For the QSBR flavor, the
-       caller should be online.
-
-pthread_t get_call_rcu_thread(struct call_rcu_data *crdp);
-
-       Returns the helper thread's pthread identifier linked to a call
-       rcu helper thread data.
-
-void set_thread_call_rcu_data(struct call_rcu_data *crdp);
-
-       Sets the current thread's hard-assigned call_rcu() helper to the
-       handle specified by "crdp".  Note that "crdp" can be NULL to
-       disassociate this thread from its helper.  Once a thread is
-       disassociated from its helper, further call_rcu() invocations
-       use the current CPU's helper if there is one and the default
-       helper otherwise.
-
-int set_cpu_call_rcu_data(int cpu, struct call_rcu_data *crdp);
-
-       Sets the specified CPU's call_rcu() helper to the handle
-       specified by "crdp".  Again, "crdp" can be NULL to disassociate
-       this CPU from its helper thread.  Once a CPU has been
-       disassociated from its helper, further call_rcu() invocations
-       that would otherwise have used this CPU's helper will instead
-       use the default helper.  The caller must wait for a grace-period
-       to pass between return from set_cpu_call_rcu_data() and call to
-       call_rcu_data_free() passing the previous call rcu data as
-       argument.
-
-int create_all_cpu_call_rcu_data(unsigned long flags)
-
-       Creates a separate call_rcu() helper thread for each CPU.
-       After this primitive is invoked, the global default call_rcu()
-       helper thread will not be called.
-
-       The set_thread_call_rcu_data(), set_cpu_call_rcu_data(), and
-       create_all_cpu_call_rcu_data() functions may be combined to set up
-       pretty much any desired association between worker and call_rcu()
-       helper threads.  If a given executable calls only call_rcu(),
-       then that executable will have only the single global default
-       call_rcu() helper thread.  This will suffice in most cases.
-
-void free_all_cpu_call_rcu_data(void);
-
-       Clean up all the per-CPU call_rcu threads. Should be paired with
-       create_all_cpu_call_rcu_data() to perform teardown. Note that
-       this function invokes synchronize_rcu() internally, so the
-       caller should be careful not to hold mutexes (or mutexes within a
-       dependency chain) that are also taken within a RCU read-side
-       critical section, or in a section where QSBR threads are online.
-
-void call_rcu_after_fork_child(void);
-
-       Should be used as pthread_atfork() handler for programs using
-       call_rcu and performing fork() or clone() without a following
-       exec().
diff --git a/doc/uatomic-api.md b/doc/uatomic-api.md
new file mode 100644 (file)
index 0000000..2dd63c6
--- /dev/null
@@ -0,0 +1,124 @@
+Userspace RCU Atomic Operations API
+===================================
+
+by Mathieu Desnoyers and Paul E. McKenney
+
+This document describes the `<urcu/uatomic.h>` API. Those are the atomic
+operations provided by the Userspace RCU library. The general rule
+regarding memory barriers is that only `uatomic_xchg()`,
+`uatomic_cmpxchg()`, `uatomic_add_return()`, and `uatomic_sub_return()` imply
+full memory barriers before and after the atomic operation. Other
+primitives don't guarantee any memory barrier.
+
+Only atomic operations performed on integers (`int` and `long`, signed
+and unsigned) are supported on all architectures. Some architectures
+also support 1-byte and 2-byte atomic operations. Those respectively
+have `UATOMIC_HAS_ATOMIC_BYTE` and `UATOMIC_HAS_ATOMIC_SHORT` defined when
+`uatomic.h` is included. An architecture trying to perform an atomic write
+to a type size not supported by the architecture will trigger an illegal
+instruction.
+
+In the description below, `type` is a type that can be atomically
+written to by the architecture. It needs to be at most word-sized, and
+its alignment needs to greater or equal to its size.
+
+
+API
+---
+
+```c
+void uatomic_set(type *addr, type v)
+```
+
+Atomically write `v` into `addr`. By "atomically", we mean that no
+concurrent operation that reads from addr will see partial
+effects of `uatomic_set()`.
+
+
+```c
+type uatomic_read(type *addr)
+```
+
+Atomically read `v` from `addr`. By "atomically", we mean that
+`uatomic_read()` cannot see a partial effect of any concurrent
+uatomic update.
+
+
+```c
+type uatomic_cmpxchg(type *addr, type old, type new)
+```
+
+An atomic read-modify-write operation that performs this
+sequence of operations atomically: check if `addr` contains `old`.
+If true, then replace the content of `addr` by `new`. Return the
+value previously contained by `addr`. This function imply a full
+memory barrier before and after the atomic operation.
+
+
+```c
+type uatomic_xchg(type *addr, type new)
+```
+
+An atomic read-modify-write operation that performs this sequence
+of operations atomically: replace the content of `addr` by `new`,
+and return the value previously contained by `addr`. This
+function imply a full memory barrier before and after the atomic
+operation.
+
+
+```c
+type uatomic_add_return(type *addr, type v)
+type uatomic_sub_return(type *addr, type v)
+```
+
+An atomic read-modify-write operation that performs this
+sequence of operations atomically: increment/decrement the
+content of `addr` by `v`, and return the resulting value. This
+function imply a full memory barrier before and after the atomic
+operation.
+
+
+```c
+void uatomic_and(type *addr, type mask)
+void uatomic_or(type *addr, type mask)
+```
+
+Atomically write the result of bitwise "and"/"or" between the
+content of `addr` and `mask` into `addr`.
+
+These operations do not necessarily imply memory barriers.
+If memory barriers are needed, they may be provided by explicitly using
+`cmm_smp_mb__before_uatomic_and()`, `cmm_smp_mb__after_uatomic_and()`,
+`cmm_smp_mb__before_uatomic_or()`, and `cmm_smp_mb__after_uatomic_or()`.
+These explicit barriers are no-ops on architectures in which the underlying
+atomic instructions implicitly supply the needed memory barriers.
+
+
+```c
+void uatomic_add(type *addr, type v)
+void uatomic_sub(type *addr, type v)
+```
+
+Atomically increment/decrement the content of `addr` by `v`.
+These operations do not necessarily imply memory barriers.
+If memory barriers are needed, they may be provided by
+explicitly using `cmm_smp_mb__before_uatomic_add()`,
+`cmm_smp_mb__after_uatomic_add()`, `cmm_smp_mb__before_uatomic_sub()`, and
+`cmm_smp_mb__after_uatomic_sub()`. These explicit barriers are
+no-ops on architectures in which the underlying atomic
+instructions implicitly supply the needed memory barriers.
+
+
+```c
+void uatomic_inc(type *addr)
+void uatomic_dec(type *addr)
+```
+
+Atomically increment/decrement the content of `addr` by 1.
+These operations do not necessarily imply memory barriers.
+If memory barriers are needed, they may be provided by
+explicitly using `cmm_smp_mb__before_uatomic_inc()`,
+`cmm_smp_mb__after_uatomic_inc()`, `cmm_smp_mb__before_uatomic_dec()`,
+and `cmm_smp_mb__after_uatomic_dec()`. These explicit barriers are
+no-ops on architectures in which the underlying atomic
+instructions implicitly supply the needed memory barriers.
diff --git a/doc/uatomic-api.txt b/doc/uatomic-api.txt
deleted file mode 100644 (file)
index edb7d4f..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-Userspace RCU Atomic Operations API
-by Mathieu Desnoyers and Paul E. McKenney
-
-
-This document describes the <urcu/uatomic.h> API. Those are the atomic
-operations provided by the Userspace RCU library. The general rule
-regarding memory barriers is that only uatomic_xchg(),
-uatomic_cmpxchg(), uatomic_add_return(), and uatomic_sub_return() imply
-full memory barriers before and after the atomic operation. Other
-primitives don't guarantee any memory barrier.
-
-Only atomic operations performed on integers ("int" and "long", signed
-and unsigned) are supported on all architectures. Some architectures
-also support 1-byte and 2-byte atomic operations. Those respectively
-have UATOMIC_HAS_ATOMIC_BYTE and UATOMIC_HAS_ATOMIC_SHORT defined when
-uatomic.h is included. An architecture trying to perform an atomic write
-to a type size not supported by the architecture will trigger an illegal
-instruction.
-
-In the description below, "type" is a type that can be atomically
-written to by the architecture. It needs to be at most word-sized, and
-its alignment needs to greater or equal to its size.
-
-void uatomic_set(type *addr, type v)
-
-       Atomically write @v into @addr. By "atomically", we mean that no
-       concurrent operation that reads from addr will see partial
-       effects of uatomic_set().
-
-type uatomic_read(type *addr)
-
-       Atomically read @v from @addr. By "atomically", we mean that
-       uatomic_read() cannot see a partial effect of any concurrent
-       uatomic update.
-
-type uatomic_cmpxchg(type *addr, type old, type new)
-
-       An atomic read-modify-write operation that performs this
-       sequence of operations atomically: check if @addr contains @old.
-       If true, then replace the content of @addr by @new. Return the
-       value previously contained by @addr. This function imply a full
-       memory barrier before and after the atomic operation.
-
-type uatomic_xchg(type *addr, type new)
-
-       An atomic read-modify-write operation that performs this sequence
-       of operations atomically: replace the content of @addr by @new,
-       and return the value previously contained by @addr. This
-       function imply a full memory barrier before and after the atomic
-       operation.
-
-type uatomic_add_return(type *addr, type v)
-type uatomic_sub_return(type *addr, type v)
-
-       An atomic read-modify-write operation that performs this
-       sequence of operations atomically: increment/decrement the
-       content of @addr by @v, and return the resulting value. This
-       function imply a full memory barrier before and after the atomic
-       operation.
-
-void uatomic_and(type *addr, type mask)
-void uatomic_or(type *addr, type mask)
-
-       Atomically write the result of bitwise "and"/"or" between the
-       content of @addr and @mask into @addr.
-       These operations do not necessarily imply memory barriers.
-       If memory barriers are needed, they may be provided by
-       explicitly using
-       cmm_smp_mb__before_uatomic_and(),
-       cmm_smp_mb__after_uatomic_and(),
-       cmm_smp_mb__before_uatomic_or(), and
-       cmm_smp_mb__after_uatomic_or(). These explicit barriers are
-       no-ops on architectures in which the underlying atomic
-       instructions implicitly supply the needed memory barriers.
-
-void uatomic_add(type *addr, type v)
-void uatomic_sub(type *addr, type v)
-
-       Atomically increment/decrement the content of @addr by @v.
-       These operations do not necessarily imply memory barriers.
-       If memory barriers are needed, they may be provided by
-       explicitly using
-       cmm_smp_mb__before_uatomic_add(),
-       cmm_smp_mb__after_uatomic_add(),
-       cmm_smp_mb__before_uatomic_sub(), and
-       cmm_smp_mb__after_uatomic_sub(). These explicit barriers are 
-       no-ops on architectures in which the underlying atomic
-       instructions implicitly supply the needed memory barriers.
-
-void uatomic_inc(type *addr)
-void uatomic_dec(type *addr)
-
-       Atomically increment/decrement the content of @addr by 1.
-       These operations do not necessarily imply memory barriers.
-       If memory barriers are needed, they may be provided by
-       explicitly using
-       cmm_smp_mb__before_uatomic_inc(),
-       cmm_smp_mb__after_uatomic_inc(),
-       cmm_smp_mb__before_uatomic_dec(), and
-       cmm_smp_mb__after_uatomic_dec(). These explicit barriers are
-       no-ops on architectures in which the underlying atomic
-       instructions implicitly supply the needed memory barriers.
index 30388c5316776bac79722f541ccdf370ccbf7549..98807ea134f8e177bf2e3d432ace5f6a0f98a367 100644 (file)
@@ -64,7 +64,7 @@ struct rcu_head {
 /*
  * Exported functions
  *
- * Important: see rcu-api.txt in userspace-rcu documentation for
+ * Important: see rcu-api.md in userspace-rcu documentation for
  * call_rcu family of functions usage detail, including the surrounding
  * RCU usage required when using these primitives.
  */
This page took 0.035047 seconds and 4 git commands to generate.