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