]> git.pld-linux.org Git - packages/db4.7.git/blame - patch.4.7.25.3
drop (incomplete) epoch 0
[packages/db4.7.git] / patch.4.7.25.3
CommitLineData
77a24bd5
AM
1*** lock/lock_deadlock.c 2008-03-11 00:31:33.000000000 +1100
2--- lock/lock_deadlock.c 2008-12-16 21:54:18.000000000 +1100
3***************
4*** 121,127 ****
5 DB_LOCKTAB *lt;
6 db_timespec now;
7 locker_info *idmap;
8! u_int32_t *bitmap, *copymap, **deadp, **free_me, *tmpmap;
9 u_int32_t i, cid, keeper, killid, limit, nalloc, nlockers;
10 u_int32_t lock_max, txn_max;
11 int ret, status;
12--- 121,127 ----
13 DB_LOCKTAB *lt;
14 db_timespec now;
15 locker_info *idmap;
16! u_int32_t *bitmap, *copymap, **deadp, **deadlist, *tmpmap;
17 u_int32_t i, cid, keeper, killid, limit, nalloc, nlockers;
18 u_int32_t lock_max, txn_max;
19 int ret, status;
20***************
21*** 133,139 ****
22 if (IS_REP_CLIENT(env))
23 atype = DB_LOCK_MINWRITE;
24
25! free_me = NULL;
26
27 lt = env->lk_handle;
28 if (rejectp != NULL)
29--- 133,140 ----
30 if (IS_REP_CLIENT(env))
31 atype = DB_LOCK_MINWRITE;
32
33! copymap = tmpmap = NULL;
34! deadlist = NULL;
35
36 lt = env->lk_handle;
37 if (rejectp != NULL)
38***************
39*** 179,189 ****
40 memcpy(copymap, bitmap, nlockers * sizeof(u_int32_t) * nalloc);
41
42 if ((ret = __os_calloc(env, sizeof(u_int32_t), nalloc, &tmpmap)) != 0)
43! goto err1;
44
45 /* Find a deadlock. */
46 if ((ret =
47! __dd_find(env, bitmap, idmap, nlockers, nalloc, &deadp)) != 0)
48 return (ret);
49
50 /*
51--- 180,190 ----
52 memcpy(copymap, bitmap, nlockers * sizeof(u_int32_t) * nalloc);
53
54 if ((ret = __os_calloc(env, sizeof(u_int32_t), nalloc, &tmpmap)) != 0)
55! goto err;
56
57 /* Find a deadlock. */
58 if ((ret =
59! __dd_find(env, bitmap, idmap, nlockers, nalloc, &deadlist)) != 0)
60 return (ret);
61
62 /*
63***************
64*** 204,211 ****
65 txn_max = TXN_MAXIMUM;
66
67 killid = BAD_KILLID;
68! free_me = deadp;
69! for (; *deadp != NULL; deadp++) {
70 if (rejectp != NULL)
71 ++*rejectp;
72 killid = (u_int32_t)(*deadp - bitmap) / nalloc;
73--- 205,211 ----
74 txn_max = TXN_MAXIMUM;
75
76 killid = BAD_KILLID;
77! for (deadp = deadlist; *deadp != NULL; deadp++) {
78 if (rejectp != NULL)
79 ++*rejectp;
80 killid = (u_int32_t)(*deadp - bitmap) / nalloc;
81***************
82*** 342,352 ****
83 __db_msg(env,
84 "Aborting locker %lx", (u_long)idmap[killid].id);
85 }
86! __os_free(env, tmpmap);
87! err1: __os_free(env, copymap);
88!
89! err: if (free_me != NULL)
90! __os_free(env, free_me);
91 __os_free(env, bitmap);
92 __os_free(env, idmap);
93
94--- 342,353 ----
95 __db_msg(env,
96 "Aborting locker %lx", (u_long)idmap[killid].id);
97 }
98! err: if(copymap != NULL)
99! __os_free(env, copymap);
100! if (deadlist != NULL)
101! __os_free(env, deadlist);
102! if(tmpmap != NULL)
103! __os_free(env, tmpmap);
104 __os_free(env, bitmap);
105 __os_free(env, idmap);
106
107***************
108*** 360,365 ****
109--- 361,377 ----
110
111 #define DD_INVALID_ID ((u_int32_t) -1)
112
113+ /*
114+ * __dd_build --
115+ * Build the lock dependency bit maps.
116+ * Notes on syncronization:
117+ * LOCK_SYSTEM_LOCK is used to hold objects locked when we have
118+ * a single partition.
119+ * LOCK_LOCKERS is held while we are walking the lockers list and
120+ * to single thread the use of lockerp->dd_id.
121+ * LOCK_DD protects the DD list of objects.
122+ */
123+
124 static int
125 __dd_build(env, atype, bmp, nlockers, allocp, idmap, rejectp)
126 ENV *env;
127***************
128*** 393,398 ****
129--- 405,411 ----
130 * In particular we do not build the conflict array and our caller
131 * needs to expect this.
132 */
133+ LOCK_SYSTEM_LOCK(lt, region);
134 if (atype == DB_LOCK_EXPIRE) {
135 skip: LOCK_DD(env, region);
136 op = SH_TAILQ_FIRST(&region->dd_objs, __db_lockobj);
137***************
138*** 430,446 ****
139 OBJECT_UNLOCK(lt, region, indx);
140 }
141 UNLOCK_DD(env, region);
142 goto done;
143 }
144
145 /*
146! * We'll check how many lockers there are, add a few more in for
147! * good measure and then allocate all the structures. Then we'll
148! * verify that we have enough room when we go back in and get the
149! * mutex the second time.
150 */
151! retry: count = region->stat.st_nlockers;
152 if (count == 0) {
153 *nlockers = 0;
154 return (0);
155 }
156--- 443,460 ----
157 OBJECT_UNLOCK(lt, region, indx);
158 }
159 UNLOCK_DD(env, region);
160+ LOCK_SYSTEM_UNLOCK(lt, region);
161 goto done;
162 }
163
164 /*
165! * Allocate after locking the region
166! * to make sure the structures are large enough.
167 */
168! LOCK_LOCKERS(env, region);
169! count = region->stat.st_nlockers;
170 if (count == 0) {
171+ UNLOCK_LOCKERS(env, region);
172 *nlockers = 0;
173 return (0);
174 }
175***************
176*** 448,497 ****
177 if (FLD_ISSET(env->dbenv->verbose, DB_VERB_DEADLOCK))
178 __db_msg(env, "%lu lockers", (u_long)count);
179
180- count += 20;
181 nentries = (u_int32_t)DB_ALIGN(count, 32) / 32;
182
183! /*
184! * Allocate enough space for a count by count bitmap matrix.
185! *
186! * XXX
187! * We can probably save the malloc's between iterations just
188! * reallocing if necessary because count grew by too much.
189! */
190 if ((ret = __os_calloc(env, (size_t)count,
191! sizeof(u_int32_t) * nentries, &bitmap)) != 0)
192 return (ret);
193
194 if ((ret = __os_calloc(env,
195 sizeof(u_int32_t), nentries, &tmpmap)) != 0) {
196 __os_free(env, bitmap);
197 return (ret);
198 }
199
200 if ((ret = __os_calloc(env,
201 (size_t)count, sizeof(locker_info), &id_array)) != 0) {
202 __os_free(env, bitmap);
203 __os_free(env, tmpmap);
204 return (ret);
205 }
206
207 /*
208- * Now go back in and actually fill in the matrix.
209- */
210- if (region->stat.st_nlockers > count) {
211- __os_free(env, bitmap);
212- __os_free(env, tmpmap);
213- __os_free(env, id_array);
214- goto retry;
215- }
216-
217- /*
218 * First we go through and assign each locker a deadlock detector id.
219 */
220 id = 0;
221- LOCK_LOCKERS(env, region);
222 SH_TAILQ_FOREACH(lip, &region->lockers, ulinks, __db_locker) {
223 if (lip->master_locker == INVALID_ROFF) {
224 lip->dd_id = id++;
225 id_array[lip->dd_id].id = lip->id;
226 switch (atype) {
227--- 462,498 ----
228 if (FLD_ISSET(env->dbenv->verbose, DB_VERB_DEADLOCK))
229 __db_msg(env, "%lu lockers", (u_long)count);
230
231 nentries = (u_int32_t)DB_ALIGN(count, 32) / 32;
232
233! /* Allocate enough space for a count by count bitmap matrix. */
234 if ((ret = __os_calloc(env, (size_t)count,
235! sizeof(u_int32_t) * nentries, &bitmap)) != 0) {
236! UNLOCK_LOCKERS(env, region);
237 return (ret);
238+ }
239
240 if ((ret = __os_calloc(env,
241 sizeof(u_int32_t), nentries, &tmpmap)) != 0) {
242+ UNLOCK_LOCKERS(env, region);
243 __os_free(env, bitmap);
244 return (ret);
245 }
246
247 if ((ret = __os_calloc(env,
248 (size_t)count, sizeof(locker_info), &id_array)) != 0) {
249+ UNLOCK_LOCKERS(env, region);
250 __os_free(env, bitmap);
251 __os_free(env, tmpmap);
252 return (ret);
253 }
254
255 /*
256 * First we go through and assign each locker a deadlock detector id.
257 */
258 id = 0;
259 SH_TAILQ_FOREACH(lip, &region->lockers, ulinks, __db_locker) {
260 if (lip->master_locker == INVALID_ROFF) {
261+ DB_ASSERT(env, id < count);
262 lip->dd_id = id++;
263 id_array[lip->dd_id].id = lip->id;
264 switch (atype) {
265***************
266*** 510,516 ****
267 lip->dd_id = DD_INVALID_ID;
268
269 }
270- UNLOCK_LOCKERS(env, region);
271
272 /*
273 * We only need consider objects that have waiters, so we use
274--- 511,516 ----
275***************
276*** 669,675 ****
277 * status after building the bit maps so that we will not detect
278 * a blocked transaction without noting that it is already aborting.
279 */
280- LOCK_LOCKERS(env, region);
281 for (id = 0; id < count; id++) {
282 if (!id_array[id].valid)
283 continue;
284--- 669,674 ----
285***************
286*** 738,743 ****
287--- 737,743 ----
288 id_array[id].in_abort = 1;
289 }
290 UNLOCK_LOCKERS(env, region);
291+ LOCK_SYSTEM_UNLOCK(lt, region);
292
293 /*
294 * Now we can release everything except the bitmap matrix that we
295***************
296*** 839,844 ****
297--- 839,845 ----
298 ret = 0;
299
300 /* We must lock so this locker cannot go away while we abort it. */
301+ LOCK_SYSTEM_LOCK(lt, region);
302 LOCK_LOCKERS(env, region);
303
304 /*
305***************
306*** 895,900 ****
307--- 896,902 ----
308 done: OBJECT_UNLOCK(lt, region, info->last_ndx);
309 err:
310 out: UNLOCK_LOCKERS(env, region);
311+ LOCK_SYSTEM_UNLOCK(lt, region);
312 return (ret);
313 }
314
This page took 0.05344 seconds and 4 git commands to generate.