~ubuntu-branches/ubuntu/lucid/libatomic-ops/lucid

« back to all changes in this revision

Viewing changes to README

  • Committer: Bazaar Package Importer
  • Author(s): Ian Wienand
  • Date: 2006-10-16 09:45:29 UTC
  • mfrom: (2.1.4 dapper)
  • Revision ID: james.westby@ubuntu.com-20061016094529-r3bevpq5w6g3rv20
Tags: 1.1-4
* Closes: #322027, #338469 -- add 04_m68k.patch for M68K support, from
  Roman Zippel <zippel@linux-m68k.org>.  Add note in README.Debian about
  port.
* Change mainatiner address to my @debian.org

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
Usage:
2
 
1) ./configure; make; make check; make install as usual
3
 
 
4
 
2) Applications should include atomic_ops.h.  Nearly all operations
5
 
are implemented by header files included from it.  It is sometimes
6
 
necessary, and always recommended to also link against atomic_ops.a.
7
 
 
8
 
Description:
9
 
Atomic_ops.h defines a large collection of operations, each one of which is a
10
 
combination of an (optional) atomic memory operation, and a memory barrier.
11
 
Also defines associated feature-test macros to determine whether a particular
12
 
operation is available on the current target hardware (either directly or
13
 
by synthesis).  This is an attempt to replace various existing files with
14
 
similar goals, since they usually do not handle differences in memory
15
 
barrier styles with sufficient generality.
16
 
 
17
 
If this is included after defining AO_REQUIRE_CAS, then the package
18
 
will make an attempt to emulate compare-and-swap in a way that (at least
19
 
on Linux) should still be async-signal-safe.  As a result, most other
20
 
atomic operations will then be defined using the compare-and-swap
21
 
emulation.  This emulation is slow, since it needs to disable signals.
22
 
And it needs to block in case of contention.  If you care about performance on
23
 
a platform that can't directly provide compare-and-swap, there are
24
 
probably better alternatives.  But this allows easy ports to some such
25
 
platforms (e.g. PA_RISC).  The option is ignored if compare-and-swap
26
 
can be implemented directly.
27
 
 
28
 
If atomic_ops.h is included after defining AO_USE_PTHREAD_DEFS, then all
29
 
atomic operations will be emulated with pthread locking.  This is NOT
30
 
async-signal-safe.  And it is slow.  It is intended primarily for debugging
31
 
of the atomic_ops package itself.
32
 
 
33
 
Note that the implementation reflects our understanding of real processor
34
 
behavior.  This occasionally diverges from the documented behavior.  (E.g.
35
 
the documented X86 behavior seems to be weak enough that it is impractical
36
 
to use.  Current real implementations appear to be much better behaved.)
37
 
We of course are in no position to guarantee that future processors
38
 
(even HPs) will continue to behave this way, though we hope they will.
39
 
 
40
 
This is a work in progress.  Corrections/additions for other platforms are
41
 
greatly appreciated.  It passes rudimentary tests on X86, Itanium, and
42
 
Alpha.
43
 
 
44
 
The defined operations are all of the form AO_<op><barrier>(<args>).
45
 
Most operations operate on values of type AO_t, which are unsigned integers
46
 
whose size matches that of pointers on the given architecture.  We may
47
 
provide more flexibility in operand types in the future, but this seems
48
 
to cover 90+% of common usage.
49
 
 
50
 
The <op> component specifies an atomic memory operation.  It may be
51
 
one of the following, where the corresponding argument and result types
52
 
are also specified:
53
 
 
54
 
void nop()
55
 
        No atomic operation.  The barrier may still be useful.
56
 
AO_t load(volatile AO_t * addr)
57
 
        Atomic load of *addr.
58
 
void store(volatile AO_t * addr, AO_t new_val)
59
 
        Atomically store new_val to *addr.
60
 
AO_t fetch_and_add(volatile AO_t *addr, AO_t incr)
61
 
        Atomically add incr to *addr, and return the original value of *addr.
62
 
AO_t fetch_and_add1(volatile AO_t *addr)
63
 
        Equivalent to AO_fetch_and_add(addr, 1).
64
 
AO_t fetch_and_sub1(volatile AO_t *addr)
65
 
        Equivalent to AO_fetch_and_add(addr, (AO_t)(-1)).
66
 
void or(volatile AO_t *addr, AO_t incr)
67
 
        Atomically or incr into *addr.
68
 
int compare_and_swap(volatile AO_t * addr, AO_t old_val, AO_t new_val)
69
 
        Atomically compare *addr to old_val, and replace *addr by new_val
70
 
        if the first comparison succeeds.  Returns nonzero if the comparison
71
 
        succeeded and *addr was updated.
72
 
AO_TS_VAL_t test_and_set(volatile AO_TS_T * addr)
73
 
        Atomically read the binary value at *addr, and set it.  AO_TS_VAL_t
74
 
        is an enumeration type which includes the two values AO_TS_SET and
75
 
        and AO_TS_CLEAR.  An AO_TS_T location is capable of holding an
76
 
        AO_TS_VAL_t, but may be much larger, as dictated by hardware
77
 
        constraints.  Test_and_set logically sets the value to AO_TS_SET.
78
 
        It may be reset to AO_TS_CLEAR with the AO_CLEAR(AO_TS_T *) macro.
79
 
        AO_TS_T locations should be initialized to AO_TS_INITIALIZER.
80
 
        The values of AO_TS_SET and AO_TS_CLEAR are hardware dependent.
81
 
        (On PA-RISC, AO_TS_SET is zero!)
82
 
 
83
 
Test_and_set is a more limited version of compare_and_swap.  Its only
84
 
advantage is that it is more easily implementable on some hardware.  It
85
 
should thus be used if only binary test-and-set functionality is needed.
86
 
 
87
 
Each operation name also includes a suffix that specifies the associated
88
 
memory barrier.  It is one of the following:
89
 
 
90
 
<none>: No memory barrier.  A plain AO_nop() really does nothing.
91
 
_release: Earlier operations must become visible to other threads
92
 
          before the atomic operation.
93
 
_acquire: Later operations must become visible after this operation.
94
 
_read: Subsequent reads must become visible after reads included in
95
 
       the atomic operation or preceding it.
96
 
_write: Earlier writes become visible before writes during or after
97
 
        the atomic operation.
98
 
_full: Ordered with respect to both earlier and later memops.
99
 
_release_write: Ordered with respect to earlier writes.  This is
100
 
                normally implemented as either a _write or _release
101
 
                barrier.
102
 
_acquire_read: Ordered with respect to later reads.  Usually implemented
103
 
               as either a _read or _acquire barrier.
104
 
 
105
 
It is possible to test whether AO_<op><barrier> is available on the
106
 
current platform by checking whether AO_HAVE_<op>_<barrier> is defined
107
 
as a macro.
108
 
 
109
 
Note that we generally don't implement operations that are either
110
 
meaningless (e.g. AO_nop_acquire, AO_nop_release) or which appear to
111
 
have no clear use (e.g. AO_load_release, AO_store_acquire, AO_load_write,
112
 
AO_store_read).  On some platforms (e.g. PA-RISC) many operations
113
 
will remain undefined unless AO_REQUIRE_CAS is defined before including
114
 
the package.
115
 
 
116
 
When typed in the package build directory, the following command
117
 
will print operations that are unimplemented on the platform:
118
 
 
119
 
make test_atomic; ./test_atomic
120
 
 
121
 
The following command generates a file "list_atomic.i" containing the
122
 
macro expansions of all implemented operations on the platform:
123
 
 
124
 
make list_atomic.i
125
 
 
126
 
Future directions:
127
 
 
128
 
We expect the list of memory barrier types to remain more or less fixed.
129
 
However, it is likely that the list of underlying atomic operations will
130
 
grow.  It would also be useful to support double-wide and narrower operations
131
 
when available.
132
 
 
133
 
Example:
134
 
 
135
 
If you want to initialize an object, and then "publish" a pointer to it
136
 
in a global location p, such that other threads reading the new value of
137
 
p are guaranteed to see an initialized object, it suffices to use
138
 
AO_release_write(p, ...) to write the pointer to the object, and to
139
 
retrieve it in other threads with AO_acquire_read(p).
140
 
 
141
 
Platform notes:
142
 
 
143
 
All X86: We quietly assume 486 or better.
144
 
 
145
 
Windows:
146
 
Currently AO_REQUIRE_CAS is not supported.
147
 
 
148
 
Microsoft compilers:
149
 
Define AO_ASSUME_WINDOWS98 to get access to hardware compare-and-swap
150
 
functionality.  This relies on the InterlockedCompareExchange() function
151
 
which was apparently not supported in Windows95.  (There may be a better
152
 
way to get access to this.)  Currently only X86(32 bit) is supported for
153
 
Windows.
154
 
 
155
 
Gcc on x86:
156
 
Define AO_USE_PNETIUM4_INSTRS to use the Pentium 4 mfence instruction.
157
 
Currently this is appears to be of marginal benefit.
158
 
 
 
1
This package provides semi-portable access to hardware provided
 
2
atomic memory operations.  These might allow you to write code:
 
3
 
 
4
- That does more interesting things in signal handlers.
 
5
- Makes more effective use of multiprocessors by allowing you to write
 
6
  clever lock-free code.  Note that such code is very difficult to get
 
7
  right, and will unavoidably be less portable than lock-based code.  It
 
8
  ia also not always faster than lock-based code.  But it may occasionally
 
9
  be a large performance win.
 
10
- To experiment with new and much better thread programming paradigms, etc.
 
11
 
 
12
For details and licensing restrictions see the files in the doc
 
13
subdirectory.