]> git.pld-linux.org Git - packages/db4.7.git/blob - patch.4.7.25.3
- apidocs subpackage
[packages/db4.7.git] / patch.4.7.25.3
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.078862 seconds and 3 git commands to generate.