93 (avoid change of the dictionary while accessing)" |
93 (avoid change of the dictionary while accessing)" |
94 |
94 |
95 |val| |
95 |val| |
96 |
96 |
97 (OperatingSystem blockInterrupts) ifTrue:[ |
97 (OperatingSystem blockInterrupts) ifTrue:[ |
98 "/ already blocked |
98 "/ already blocked |
99 ^ super at:key ifAbsent:exceptionBlock. |
99 ^ super at:key ifAbsent:exceptionBlock. |
100 ]. |
100 ]. |
101 |
101 |
102 [ |
102 [ |
103 val := super at:key ifAbsent:exceptionBlock. |
103 val := super at:key ifAbsent:exceptionBlock. |
104 ] valueNowOrOnUnwindDo:[ |
104 ] valueNowOrOnUnwindDo:[ |
105 OperatingSystem unblockInterrupts. |
105 OperatingSystem unblockInterrupts. |
106 ]. |
106 ]. |
107 ^ val |
107 ^ val |
108 |
108 |
109 "Modified: 6.5.1996 / 12:22:26 / stefan" |
109 "Modified: 6.5.1996 / 12:22:26 / stefan" |
110 "Modified: 1.7.1997 / 10:45:47 / cg" |
110 "Modified: 1.7.1997 / 10:45:47 / cg" |
117 are added within interrupting high prio processes." |
117 are added within interrupting high prio processes." |
118 |
118 |
119 |val| |
119 |val| |
120 |
120 |
121 (OperatingSystem blockInterrupts) ifTrue:[ |
121 (OperatingSystem blockInterrupts) ifTrue:[ |
122 "/ already blocked |
122 "/ already blocked |
123 ^ super at:key put:anObject. |
123 ^ super at:key put:anObject. |
124 ]. |
124 ]. |
125 |
125 |
126 [ |
126 [ |
127 val := super at:key put:anObject. |
127 val := super at:key put:anObject. |
128 ] valueNowOrOnUnwindDo:[ |
128 ] valueNowOrOnUnwindDo:[ |
129 OperatingSystem unblockInterrupts. |
129 OperatingSystem unblockInterrupts. |
130 ]. |
130 ]. |
131 ^ val |
131 ^ val |
132 |
132 |
133 "Modified: 6.5.1996 / 12:22:26 / stefan" |
133 "Modified: 6.5.1996 / 12:22:26 / stefan" |
134 "Modified: 29.1.1997 / 15:08:45 / cg" |
134 "Modified: 29.1.1997 / 15:08:45 / cg" |
135 ! |
135 ! |
136 |
136 |
137 removeKey:aKey ifAbsent:aBlock |
137 removeKey:aKey ifAbsent:aBlock |
138 "remove the association under aKey from the collection, |
138 "remove the association under aKey from the collection, |
139 return the value previously stored there.. |
139 return the value previously stored there. |
140 If it was not in the collection return the result |
140 If it was not in the collection return the result |
141 from evaluating aBlock. |
141 from evaluating aBlock. |
142 |
142 |
143 Redefined to avoid synchronization problems, in case |
143 Redefined to avoid synchronization problems, in case |
144 of interrupts (otherwise, there could be some other operation |
144 of interrupts (otherwise, there could be some other operation |
145 on the receiver done by another process, which garbles my contents)." |
145 on the receiver done by another process, which garbles my contents)." |
146 |
146 |
147 |ret| |
147 |ret| |
148 |
148 |
149 (OperatingSystem blockInterrupts) ifTrue:[ |
149 (OperatingSystem blockInterrupts) ifTrue:[ |
150 "/ already blocked |
150 "/ already blocked |
151 ^ super removeKey:aKey ifAbsent:aBlock. |
151 ^ super removeKey:aKey ifAbsent:aBlock. |
152 ]. |
152 ]. |
153 |
153 |
154 [ |
154 [ |
155 ret := super removeKey:aKey ifAbsent:aBlock |
155 ret := super removeKey:aKey ifAbsent:aBlock |
156 ] valueNowOrOnUnwindDo:[ |
156 ] valueNowOrOnUnwindDo:[ |
157 OperatingSystem unblockInterrupts |
157 OperatingSystem unblockInterrupts |
158 ]. |
158 ]. |
159 ^ ret |
159 ^ ret |
160 |
160 |
161 "Modified: 6.5.1996 / 12:44:51 / stefan" |
161 "Modified: 6.5.1996 / 12:44:51 / stefan" |
162 "Modified: 29.1.1997 / 15:09:11 / cg" |
162 "Modified: 29.1.1997 / 15:09:11 / cg" |
167 (avoid change of the dictionary while accessing)" |
167 (avoid change of the dictionary while accessing)" |
168 |
168 |
169 |val| |
169 |val| |
170 |
170 |
171 (OperatingSystem blockInterrupts) ifTrue:[ |
171 (OperatingSystem blockInterrupts) ifTrue:[ |
172 "/ already blocked |
172 "/ already blocked |
173 ^ super saveRemoveKey:key. |
173 ^ super saveRemoveKey:key. |
174 ]. |
174 ]. |
175 |
175 |
176 [ |
176 [ |
177 val := super saveRemoveKey:key. |
177 val := super saveRemoveKey:key. |
178 ] valueNowOrOnUnwindDo:[ |
178 ] valueNowOrOnUnwindDo:[ |
179 OperatingSystem unblockInterrupts. |
179 OperatingSystem unblockInterrupts. |
180 ]. |
180 ]. |
181 ^ val |
181 ^ val |
182 |
182 |
183 "Modified: 6.5.1996 / 12:22:26 / stefan" |
183 "Modified: 6.5.1996 / 12:22:26 / stefan" |
184 "Modified: 1.7.1997 / 10:45:52 / cg" |
184 "Modified: 1.7.1997 / 10:45:52 / cg" |
192 disposed keys." |
192 disposed keys." |
193 |
193 |
194 |wasBlocked| |
194 |wasBlocked| |
195 |
195 |
196 something == #ElementExpired ifTrue:[ |
196 something == #ElementExpired ifTrue:[ |
197 " |
197 " |
198 have to block here - dispose may be done at a low priority |
198 have to block here - dispose may be done at a low priority |
199 from the background finalizer. If new items are added by a |
199 from the background finalizer. If new items are added by a |
200 higher prio process, the dictionary might get corrupted otherwise |
200 higher prio process, the dictionary might get corrupted otherwise |
201 " |
201 " |
202 wasBlocked := OperatingSystem blockInterrupts. |
202 wasBlocked := OperatingSystem blockInterrupts. |
203 |
203 |
204 keyArray |
204 keyArray |
205 forAllDeadIndicesDo:[:idx | |
205 forAllDeadIndicesDo:[:idx | |
206 valueArray basicAt:idx put:nil. |
206 valueArray basicAt:idx put:nil. |
207 tally := tally - 1. |
207 tally := tally - 1. |
208 ] |
208 ] |
209 replacingCorpsesWith:DeletedEntry. |
209 replacingCorpsesWith:DeletedEntry. |
210 |
210 |
211 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
211 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
212 ] |
212 ] |
213 |
213 |
214 "Created: 7.1.1997 / 16:59:30 / stefan" |
214 "Created: 7.1.1997 / 16:59:30 / stefan" |
215 ! ! |
215 ! ! |
216 |
216 |
221 If it is found, return return the index, |
221 If it is found, return return the index, |
222 otherwise the index of the first unused slot. |
222 otherwise the index of the first unused slot. |
223 Grow the receiver, if key was not found, and no unused slots were present. |
223 Grow the receiver, if key was not found, and no unused slots were present. |
224 |
224 |
225 Warning: an empty slot MUST be filled by the sender - it is only to be sent |
225 Warning: an empty slot MUST be filled by the sender - it is only to be sent |
226 by at:put: / add: - like methods." |
226 by at:put: / add: - like methods." |
227 |
227 |
228 |index "{ Class:SmallInteger }" |
228 |index "{ Class:SmallInteger }" |
229 length "{ Class:SmallInteger }" |
229 length "{ Class:SmallInteger }" |
230 startIndex probe |
230 startIndex probe |
231 delIndex "{ Class:SmallInteger }"| |
231 delIndex "{ Class:SmallInteger }"| |
232 |
232 |
233 (OperatingSystem blockInterrupts) ifFalse:[ |
233 (OperatingSystem blockInterrupts) ifFalse:[ |
234 "/ |
234 "/ |
235 "/ may never be entered with interrupts enabled |
235 "/ may never be entered with interrupts enabled |
236 "/ |
236 "/ |
237 OperatingSystem unblockInterrupts. |
237 OperatingSystem unblockInterrupts. |
238 self error:'oops - unblocked call of findKeyOrNil'. |
238 self error:'oops - unblocked call of findKeyOrNil'. |
239 ^ nil "/ leads to another error, if proceeded |
239 ^ nil "/ leads to another error, if proceeded |
240 ]. |
240 ]. |
241 |
241 |
242 delIndex := 0. |
242 delIndex := 0. |
243 |
243 |
244 length := keyArray basicSize. |
244 length := keyArray basicSize. |
245 index := key identityHash. |
245 index := key identityHash. |
246 index < 16r1FFFFFFF ifTrue:[ |
246 index < 16r1FFFFFFF ifTrue:[ |
247 index := index * 2 |
247 index := index * 2 |
248 ]. |
248 ]. |
249 index := index \\ length + 1. |
249 index := index \\ length + 1. |
250 startIndex := index. |
250 startIndex := index. |
251 |
251 |
252 [true] whileTrue:[ |
252 [true] whileTrue:[ |
253 probe := keyArray basicAt:index. |
253 probe := keyArray basicAt:index. |
254 key == probe ifTrue:[^ index]. |
254 key == probe ifTrue:[^ index]. |
255 probe isNil ifTrue:[ |
255 probe isNil ifTrue:[ |
256 delIndex == 0 ifTrue:[^ index]. |
256 delIndex == 0 ifTrue:[^ index]. |
257 keyArray basicAt:delIndex put:nil. |
257 keyArray basicAt:delIndex put:nil. |
258 ^ delIndex |
258 ^ delIndex |
259 ]. |
259 ]. |
260 |
260 |
261 probe == 0 ifTrue:[ |
261 probe == 0 ifTrue:[ |
262 probe := DeletedEntry. |
262 probe := DeletedEntry. |
263 keyArray basicAt:index put:probe. |
263 keyArray basicAt:index put:probe. |
264 valueArray basicAt:index put:nil. |
264 valueArray basicAt:index put:nil. |
265 tally := tally - 1. |
265 tally := tally - 1. |
266 ]. |
266 ]. |
267 |
267 |
268 delIndex == 0 ifTrue:[ |
268 delIndex == 0 ifTrue:[ |
269 probe == DeletedEntry ifTrue:[ |
269 probe == DeletedEntry ifTrue:[ |
270 delIndex := index |
270 delIndex := index |
271 ] |
271 ] |
272 ]. |
272 ]. |
273 |
273 |
274 index == length ifTrue:[ |
274 index == length ifTrue:[ |
275 index := 1 |
275 index := 1 |
276 ] ifFalse:[ |
276 ] ifFalse:[ |
277 index := index + 1 |
277 index := index + 1 |
278 ]. |
278 ]. |
279 index == startIndex ifTrue:[ |
279 index == startIndex ifTrue:[ |
280 delIndex ~~ 0 ifTrue:[ |
280 delIndex ~~ 0 ifTrue:[ |
281 keyArray basicAt:delIndex put:nil. |
281 keyArray basicAt:delIndex put:nil. |
282 ^ delIndex |
282 ^ delIndex |
283 ]. |
283 ]. |
284 ^ self grow findKeyOrNil:key |
284 ^ self grow findKeyOrNil:key |
285 ]. |
285 ]. |
286 ] |
286 ] |
287 |
287 |
288 "Modified: 30.1.1997 / 15:04:34 / cg" |
288 "Modified: 30.1.1997 / 15:04:34 / cg" |
289 ! |
289 ! |
290 |
290 |
294 are added within interrupting high prio processes." |
294 are added within interrupting high prio processes." |
295 |
295 |
296 "/ 'grow:' printCR. |
296 "/ 'grow:' printCR. |
297 |
297 |
298 (OperatingSystem blockInterrupts) ifTrue:[ |
298 (OperatingSystem blockInterrupts) ifTrue:[ |
299 "/ already blocked |
299 "/ already blocked |
300 ^ super grow:newSize. |
300 ^ super grow:newSize. |
301 ]. |
301 ]. |
302 |
302 |
303 [ |
303 [ |
304 super grow:newSize |
304 super grow:newSize |
305 ] valueNowOrOnUnwindDo:[ |
305 ] valueNowOrOnUnwindDo:[ |
306 OperatingSystem unblockInterrupts |
306 OperatingSystem unblockInterrupts |
307 ]. |
307 ]. |
308 |
308 |
309 "Created: 28.1.1997 / 23:41:39 / cg" |
309 "Created: 28.1.1997 / 23:41:39 / cg" |
310 "Modified: 29.1.1997 / 15:10:12 / cg" |
310 "Modified: 29.1.1997 / 15:10:12 / cg" |
311 ! |
311 ! |
352 are added within interrupting high prio processes." |
352 are added within interrupting high prio processes." |
353 |
353 |
354 "/ 'setTally:' printCR. |
354 "/ 'setTally:' printCR. |
355 |
355 |
356 (OperatingSystem blockInterrupts) ifTrue:[ |
356 (OperatingSystem blockInterrupts) ifTrue:[ |
357 "/ already blocked |
357 "/ already blocked |
358 ^ super setTally:count. |
358 ^ super setTally:count. |
359 ]. |
359 ]. |
360 |
360 |
361 [ |
361 [ |
362 super setTally:count |
362 super setTally:count |
363 ] valueNowOrOnUnwindDo:[ |
363 ] valueNowOrOnUnwindDo:[ |
364 OperatingSystem unblockInterrupts |
364 OperatingSystem unblockInterrupts |
365 ]. |
365 ]. |
366 |
366 |
367 "Created: 29.1.1997 / 11:40:12 / cg" |
367 "Created: 29.1.1997 / 11:40:12 / cg" |
368 "Modified: 29.1.1997 / 15:11:11 / cg" |
368 "Modified: 29.1.1997 / 15:11:11 / cg" |
369 ! ! |
369 ! ! |
375 (avoid change of the dictionary while accessing)" |
375 (avoid change of the dictionary while accessing)" |
376 |
376 |
377 |val| |
377 |val| |
378 |
378 |
379 (OperatingSystem blockInterrupts) ifTrue:[ |
379 (OperatingSystem blockInterrupts) ifTrue:[ |
380 "/ already blocked |
380 "/ already blocked |
381 ^ super includes:anObject. |
381 ^ super includes:anObject. |
382 ]. |
382 ]. |
383 |
383 |
384 [ |
384 [ |
385 val := super includes:anObject. |
385 val := super includes:anObject. |
386 ] valueNowOrOnUnwindDo:[ |
386 ] valueNowOrOnUnwindDo:[ |
387 OperatingSystem unblockInterrupts. |
387 OperatingSystem unblockInterrupts. |
388 ]. |
388 ]. |
389 ^ val |
389 ^ val |
390 |
390 |
391 "Modified: 6.5.1996 / 12:22:26 / stefan" |
391 "Modified: 6.5.1996 / 12:22:26 / stefan" |
392 "Modified: 1.7.1997 / 10:45:52 / cg" |
392 "Modified: 1.7.1997 / 10:45:52 / cg" |
398 (avoid change of the dictionary while accessing)" |
398 (avoid change of the dictionary while accessing)" |
399 |
399 |
400 |val| |
400 |val| |
401 |
401 |
402 (OperatingSystem blockInterrupts) ifTrue:[ |
402 (OperatingSystem blockInterrupts) ifTrue:[ |
403 "/ already blocked |
403 "/ already blocked |
404 ^ super includesKey:key. |
404 ^ super includesKey:key. |
405 ]. |
405 ]. |
406 |
406 |
407 [ |
407 [ |
408 val := super includesKey:key. |
408 val := super includesKey:key. |
409 ] valueNowOrOnUnwindDo:[ |
409 ] valueNowOrOnUnwindDo:[ |
410 OperatingSystem unblockInterrupts. |
410 OperatingSystem unblockInterrupts. |
411 ]. |
411 ]. |
412 ^ val |
412 ^ val |
413 |
413 |
414 "Modified: 6.5.1996 / 12:22:26 / stefan" |
414 "Modified: 6.5.1996 / 12:22:26 / stefan" |
415 "Created: 1.7.1997 / 10:45:14 / cg" |
415 "Created: 1.7.1997 / 10:45:14 / cg" |