Browse code

improve dox

Nat! authored on 19-10-2016 14:59:40
Showing 4 changed files
... ...
@@ -1,7 +1,8 @@
1
-1.0.1-1.0.3
1
+1.0.1-1.0.4
2 2
 ===
3 3
 
4 4
 * fix packaging
5
+* improve documentation
5 6
 
6 7
 
7 8
 # v1.0
... ...
@@ -1,16 +1,19 @@
1 1
 # `mulle_concurrent_hashmap`
2 2
 
3 3
 `mulle_concurrent_hashmap` is a mutable map of pointers, indexed by a hash.
4
-Such a hashmap is extremely volatile when shared by multiple threads, that are
5
-inserting and removing entries. As an example: when you get the number of elements
6
-of a such a map it is just a fleeting glimpse of it at a now fairly distant point
7
-in time.
4
+What is it good for ?  It's good for a table, that needs to be accessed quickly
5
+and often by multiple threads. Rule of thumb, if your process is spending a lot
6
+of time locking and unlocking a central hashtable, you
7
+want `mulle_concurrent_hashmap`.
8
+
9
+Such a hashmap is extremely volatile when shared with multiple threads, that are
10
+inserting and removing entries. For example, when you get the number of elements
11
+of a such a hashmap it is akin to a fleeting glimpse of a distant past.
8 12
 
9 13
 The following operations should be executed in single-threaded fashion:
10 14
 
11 15
 * `mulle_concurrent_hashmap_init`
12 16
 * `mulle_concurrent_hashmap_done`
13
-* `mulle_concurrent_hashmap_get_size`
14 17
 
15 18
 The following operations are fine in multi-threaded environments:
16 19
 
... ...
@@ -26,6 +29,7 @@ approached with caution:
26 29
 * `mulle_concurrent_hashmapenumerator_done`
27 30
 * `mulle_concurrent_hashmap_lookup_any`
28 31
 * `mulle_concurrent_hashmap_count`
32
+* `mulle_concurrent_hashmap_get_size`
29 33
 
30 34
 
31 35
 ## single-threaded
... ...
@@ -44,9 +48,10 @@ used to allocate and free memory during the lifetime of `map`.  You can pass in
44 48
 for `allocator` to use the default. Call this in single-threaded fashion.
45 49
 
46 50
 Return Values:
47
-   0      : OK
48
-   EINVAL : invalid argument
49
-   ENOMEM : out of memory
51
+
52
+*   0      : OK
53
+*   EINVAL : invalid argument
54
+*   ENOMEM : out of memory
50 55
 
51 56
 
52 57
 ### `void  mulle_concurrent_hashmap_done`
... ...
@@ -92,9 +97,10 @@ not get dereferenced by the hashmap.
92 97
 
93 98
 
94 99
 Return Values:
95
-   0      : OK
96
-   EEXIST : duplicate
97
-   ENOMEM : out of memory
100
+
101
+*   0      : OK
102
+*   EEXIST : duplicate
103
+*   ENOMEM : out of memory
98 104
 
99 105
 
100 106
 ### `mulle_concurrent_hashmap_remove`
... ...
@@ -125,8 +131,9 @@ void   *mulle_concurrent_hashmap_lookup( struct mulle_concurrent_hashmap *map,
125 131
 Looks up a value by its hash.
126 132
 
127 133
 Return Values:
128
-   NULL  : not found
129
-   otherwise the value for this hash
134
+
135
+*   NULL  : not found
136
+*   otherwise the value for this hash
130 137
 
131 138
 ---
132 139
 
... ...
@@ -134,12 +141,11 @@ Return Values:
134 141
 ### `mulle_concurrent_hashmap_get_size`
135 142
 
136 143
 ```
137
-unsigned int   mulle_concurrent_hashmap_get_count( struct mulle_concurrent_hashmap *map);
144
+unsigned int   mulle_concurrent_hashmap_get_size( struct mulle_concurrent_hashmap *map);
138 145
 ```
139 146
 
140
-This gives you the current number of hash/value entries of `map`. The returned
141
-number is close to meaningless, when the map is accessed in multi-threaded
142
-fashion.
147
+This gives you the current capacity of hash/value entries of `map`. The returned
148
+number maybe not as meaningful as one might think, if the map is accessed in multi-threaded fashion.
143 149
 
144 150
 
145 151
 # `mulle_concurrent_hashmapenumerator`
... ...
@@ -161,13 +167,18 @@ Here is a simple usage example:
161 167
    struct mulle_concurrent_hashmapenumerator   rover;
162 168
    intptr_t                                    hash;
163 169
    void                                        *value;
170
+   int                                         rval;
164 171
 
172
+retry:
165 173
    rover = mulle_concurrent_hashmap_enumerate( map);
166
-   while( mulle_concurrent_hashmapenumerator_next( &rover, &hash, &value) == 1)
174
+   while( (rval = mulle_concurrent_hashmapenumerator_next( &rover, &hash, &value) == 1))
167 175
    {
168 176
       printf( "%ld %p\n", hash, value);
169 177
    }
170 178
    mulle_concurrent_hashmapenumerator_done( &rover);
179
+
180
+   if( rval == EBUSY)
181
+      goto retry;  // restart from the beginning
171 182
 ```
172 183
 
173 184
 ### `mulle_concurrent_hashmapenumerator_next`
... ...
@@ -181,10 +192,11 @@ int  mulle_concurrent_hashmapenumerator_next( struct mulle_concurrent_hashmapenu
181 192
 Get the next `hash`, `value` pair from the enumerator.
182 193
 
183 194
 Return Values:
184
-   1          : OK
185
-   0          : nothing left
186
-   ECANCELLED : hashtable was mutated
187
-   ENOMEM     : out of memory
195
+
196
+*   1          : OK
197
+*   0          : nothing left
198
+*   ECANCELLED : hashtable was mutated
199
+*   ENOMEM     : out of memory
188 200
 
189 201
 
190 202
 ### `mulle_concurrent_hashmapenumerator_done`
... ...
@@ -1,9 +1,9 @@
1
-# `mulle_concurrent_pointerlist`
1
+# `mulle_concurrent_pointerarray`
2 2
 
3
-`mulle_concurrent_pointerlist` is a mutable array of pointers that can only
3
+`mulle_concurrent_pointerarray` is a mutable array of pointers that can only
4 4
 grow. Such an array can be shared with multiple threads, that can access the
5
-array without locking. It's limitations are it's strength, as it makes its
6
-handling very simple.
5
+array without locking. Its limitations are its strength, as it makes the
6
+API very simple and safe.
7 7
 
8 8
 
9 9
 The following operations should be executed in single-threaded fashion:
... ...
@@ -15,10 +15,6 @@ The following operations are fine in multi-threaded environments:
15 15
 
16 16
 * `mulle_concurrent_pointerarray_add`
17 17
 * `mulle_concurrent_pointerarray_get`
18
-
19
-The following operations work in multi-threaded environments,
20
-but should be approached with caution:
21
-
22 18
 * `mulle_concurrent_pointerarray_enumerate`
23 19
 * `mulle_concurrent_pointerarrayenumerator_next`
24 20
 * `mulle_concurrent_pointerarrayenumerator_done`
... ...
@@ -74,9 +70,10 @@ not get dereferenced by the pointerarray.
74 70
 
75 71
 
76 72
 Return Values:
77
-   0      : OK
78
-   EINVAL : invalid argument
79
-   ENOMEM : out of memory
73
+
74
+*   0      : OK
75
+*   EINVAL : invalid argument
76
+*   ENOMEM : out of memory
80 77
 
81 78
 
82 79
 ### `mulle_concurrent_pointerarray_get`
... ...
@@ -89,8 +86,8 @@ void   *mulle_concurrent_pointerarray_get( struct mulle_concurrent_pointerarray
89 86
 Get value at `index` of array.
90 87
 
91 88
 Return Values:
92
-   NULL  : not found (invalid argument)
93
-   otherwise the value
89
+*   NULL  : not found (invalid argument)
90
+*   otherwise the value
94 91
 
95 92
 
96 93
 ### `mulle_concurrent_pointerarray_get_size`
... ...
@@ -121,7 +118,7 @@ grow this value is useful, but maybe already outdated.
121 118
 struct mulle_concurrent_pointerarrayenumerator  mulle_concurrent_pointerarray_enumerate( struct mulle_concurrent_pointerarray *array)
122 119
 ```
123 120
 
124
-Enumerate a pointerarray. This works reliably even in multi-threaded
121
+Enumerate a pointerarray (0 to n-1). This works reliably even in multi-threaded
125 122
 environments. The enumerator itself should not be shared with other
126 123
 threads though.
127 124
 
... ...
@@ -150,8 +147,8 @@ void   *mulle_concurrent_pointerarrayenumerator_next( struct mulle_concurrent_po
150 147
 Get the next value from the enumerator.
151 148
 
152 149
 Return Values:
153
-   NULL  : nothing left
154
-   otherwis the value
150
+*   NULL  : nothing left
151
+*   otherwise the value
155 152
 
156 153
 
157 154
 ### `mulle_concurrent_pointerarrayenumerator_done`
... ...
@@ -164,4 +161,39 @@ Mark the end of the enumerator lifetime. It's a mere conventional function.
164 161
 It may be left out.
165 162
 
166 163
 
164
+## `mulle_concurrent_pointerarrayreverseenumerator`
165
+
166
+
167
+### `mulle_concurrent_pointerarray_reverseenumerate`
168
+
169
+```
170
+struct mulle_concurrent_pointerarrayreverseenumerator  mulle_concurrent_pointerarray_reverseenumerate( struct mulle_concurrent_pointerarray *array)
171
+```
172
+
173
+Reverse enumerate a pointerarray (n-1 to 0). This works reliably even
174
+in multi-threaded environments. The enumerator itself should not be shared
175
+with other threads though.
176
+
177
+
178
+### `mulle_concurrent_pointerarrayreverseenumerator_next`
179
+
180
+```
181
+void   *mulle_concurrent_pointerarrayreverseenumerator_next( struct mulle_concurrent_pointerarrayreverseenumerator *rover)
182
+```
183
+
184
+Get the next value from the enumerator.
185
+
186
+Return Values:
187
+*   NULL  : nothing left
188
+*   otherwise the value
189
+
190
+
191
+### `mulle_concurrent_pointerarrayreverseenumerator_done`
192
+
193
+```
194
+void   mulle_concurrent_pointerarrayreverseenumerator_done( struct mulle_concurrent_pointerarrayreverseenumerator *rover)
195
+```
196
+
197
+Mark the end of the enumerator lifetime. It's a mere conventional function.
198
+It may be left out.
167 199
 
168 200
new file mode 100644
... ...
@@ -0,0 +1,121 @@
1
+# How to build mulle-concurrent
2
+
3
+
4
+## What you get
5
+
6
+* `libmulle_concurrent.a` the mulle-concurrent static libraries along with a
7
+bunch of headers.
8
+
9
+
10
+## Prerequisites
11
+
12
+#### mulle-aba
13
+
14
+[mulle-aba](//www.mulle-kybernetik.com/software/git/mulle-aba/) provides the
15
+ABA safe freeing of resources.
16
+
17
+#### mulle-allocator
18
+
19
+[mulle-allocator](//www.mulle-kybernetik.com/software/git/mulle-allocator/) contains the memory-allocation scheme, that mulle-concurrent uses.
20
+
21
+#### mulle-c11
22
+
23
+[mulle-c11](//www.mulle-kybernetik.com/software/git/mulle-c11/) is a header
24
+that abstracts a small set of non-standardized compiler features.
25
+
26
+#### mulle-configuration
27
+
28
+[mulle-configuration](//www.mulle-kybernetik.com/software/git/mulle-configuration/)
29
+are configuration files for building with Xcode or cmake. This is expected to
30
+exist in the project directory root.
31
+
32
+#### mulle-thread
33
+
34
+[mulle-thread](//www.mulle-kybernetik.com/software/git/mulle-thread/) contains
35
+the necessary atomic operations.
36
+
37
+
38
+
39
+## Nice to have
40
+
41
+#### mulle-build
42
+
43
+[mulle-build](//www.mulle-kybernetik.com/software/git/mulle-build) is used
44
+to assemble the dependencies together and build the library.
45
+
46
+#### mulle-homebrew
47
+
48
+[mulle-homebrew](//www.mulle-kybernetik.com/software/git/mulle-homebrew/) is
49
+support for generating homebrew formulae. This is expected to
50
+exist in `./bin`, if you want to release a fork.
51
+
52
+#### mulle-tests
53
+
54
+[mulle-tests](//www.mulle-kybernetik.com/software/git/mulle-tests/) are
55
+scripts to provide an environment for running the tests. This is expected to
56
+exist in `./tests`, if you want to run tests.
57
+
58
+
59
+### Windows: Installing further prerequisites
60
+
61
+Check the [mulle-build README.md](//www.mulle-kybernetik.com/software/git/mulle-build/README.md)
62
+for instrutions how to get the "Git for Windows" bash going.
63
+
64
+
65
+### OSX: Install mulle-build using homebrew
66
+
67
+Install the [homebrew](//brew.sh/) package manager, then
68
+
69
+```
70
+brew tap mulle-kybernetik/software
71
+brew install mulle-build
72
+```
73
+
74
+### Linux: Install mulle-build using linuxbrew
75
+
76
+Install the [linuxbrew](//linuxbrew.sh/) package manager, then it seems you
77
+may need `python-setuptools` dependency as well:
78
+
79
+```
80
+sudo apt-get install python-setuptools
81
+```
82
+
83
+and then
84
+
85
+```
86
+brew tap mulle-kybernetik/software
87
+brew install mulle-build
88
+```
89
+
90
+### All: Install mulle-build using git
91
+
92
+```
93
+git clone --branch release https://www.mulle-kybernetik.com/repositories/mulle-bootstrap
94
+( cd mulle-bootstrap ; ./install.sh )
95
+git clone --branch release https://www.mulle-kybernetik.com/repositories/mulle-build
96
+( cd mulle-build ; ./install.sh )
97
+```
98
+
99
+## All: Install mulle-concurrent using mulle-build
100
+
101
+
102
+Grab the latest **mulle-concurrent** release and go into the project directory:
103
+
104
+```
105
+git clone --branch release https://www.mulle-kybernetik.com/repositories/mulle-concurrent
106
+cd mulle-concurrent
107
+```
108
+
109
+Then let **mulle-build** fetch the dependencies and
110
+build **mulle-concurrent** in debug mode:
111
+
112
+```
113
+mulle-build --debug
114
+```
115
+
116
+Build library in release mode and install into `tmp` :
117
+
118
+```
119
+mulle-clean ;
120
+mulle-install --prefix /tmp
121
+```