Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Ticket #1038 (closed enhancement: fixed)

Opened 4 years ago

Last modified 2 years ago

Add a class for WeakRef and WeakHashMap

Reported by: keinfarbton Assigned to: kris
Priority: normal Milestone: 1.0
Component: Core Functionality Version: 0.99.5 Jascha
Keywords: triage Cc: larsivi, h3r3tic

Attachments

patch (6.0 kB) - added by winterwar on 12/13/09 13:58:47.

Change History

04/10/08 23:50:15 changed by kris

For now, I'd rather see a WeakHashMap? in tango.scrapple and the weakref.d to remain there. The tango.scrapple location is a staging ground for potential Tango functionality.

04/11/08 17:29:24 changed by keinfarbton

The problem is, i don't really know how to implement the WeakHashMap?. My hope was, Sean would perhaps do the magic happen. :)

04/12/08 17:18:29 changed by larsivi

  • milestone changed from 0.99.6 to 1.0.

Except that weakref is in scrapple and not tango.scrapple (maybe should have a tangofied version there), I agree with Kris. Moving out in time.

05/24/08 19:18:49 changed by larsivi

  • keywords set to triage.

11/08/09 20:15:40 changed by kris

  • owner changed from sean to fawzi.

11/29/09 07:34:18 changed by fawzi

  • owner changed from fawzi to kris.

12/13/09 13:58:24 changed by winterwar

Here's a _simple_ patch to add a WeakReference? class to Tango.

Unlike the weakref.d linked above, this one should be race condition free. It also is more GC independent (because the actual implementation is inside the GC).

A WeakReference? class or something similar definitely should be included in Tango because 1. it's hard/impossible to get it right and 2. to be sure it works with future revisions of the GC and the runtime core. Even std.singals in D2 Phobos seems to be full of race conditions, because it tries to construct its own weak pointers.

12/13/09 13:58:47 changed by winterwar

  • attachment patch added.

12/13/09 14:00:45 changed by winterwar

PS: the "hard/impossible" part is true when you're trying to add weak pointers without changing the runtime. If it's inside the runtime, it becomes trivial.

12/13/09 18:13:14 changed by winterwar

I was told to add some further comments about the patch I posted:
- WeakReference?.get() locks the global GC lock, which may cause lots of contention if the WeakReference? is often queried... as an optimization to make it faster, one could use a GC counter like Fawzi did in his previous implementation (see link in weakpointerGet() in the patch)
- doesn't provide WeakHashMap?
- the actual weak pointers are implemented inside the GC to ensure GC independence and to avoid assumptions about the GC implementation in the rest of Tango or user code using weak pointers
- the patch is mostly independent from the rest of the GC and the runtime core, so it shouldn't be possible to introduce any regressions unrelated to weak pointers
- Java provides a ReferenceQueue?, which isn't included in this patch; but it could be built on top of the existing code
Generally, the patch is intended to be as simple as possible to provide a starting ground and the basic mechanism for weak pointers in Tango, and to ensure it's correct (especially to be race condition free).

01/12/10 04:23:15 changed by kris

  • cc set to larsivi, h3r3tic.

comments, larsivi and h3r3tic?

01/12/10 12:47:47 changed by larsivi

I certainly want weak refs - weak hashmap seems to be a different request that should get its own ticket.

01/12/10 14:11:04 changed by kris

what about the merits of this implementation?

01/16/10 05:04:01 changed by h3r3tic

The patch seems OK to me, but I have some tiny nitpicks :D

  • The ctor for WeakReference? quite unnecessarily ends up calling clear() and going all the way down to the GC - this could be trivially optimized
  • weakpointerCreate initializes the WeakPointer? struct twice. Once to zeroes, then to the proper values
  • DMD/DMC's malloc is horrible in terms of multi-threaded performance. Something else should probably be used in weakpointerCreate.

Anyway, looks good. To what extent has it been tested?

01/16/10 14:19:57 changed by kris

I suggest we replace dmd malloc with something else? Either dlmalloc or nedmalloc (the latter is derived from the former, but with more efficient multi-thread synchronization)

01/16/10 20:40:17 changed by winterwar

With some work, one could remove the use of malloc altogether. Here are some ideas:

- The GC could provide the ability to allocate memory, that isn't automatically free'd as soon as it's unreachable. This would behave like malloc (at least if the "noscan" bit is set for the memory block). Let's call such memory allocations "root blocks", because they would basically form an additional GC root. This sounds trivial to implement: just put all "root blocks" into a global linked list, and when doing a GC run, walk the list and mark them. They could also be useful for user-code, e.g. bindings for C libraries: they tend to allocate all memory with C malloc, and then call the quite inefficient addRoot() to make the GC aware of it.

- Or one could make the GC scan the finalizer delegate (passed to rt_attachDisposeEvent()) for pointers. But looking at the code, this doesn't seem to be simple at all (it uses C's malloc). (One could make rt_attachDisposeEvent use the "root blocks" mentioned above, but I'm not so sure if that would be deadlock free and all that.)

Also, having to acquire the GC lock in every weakpointerGet() call is probably the thing that could kill performance most. Doing the same thing as Fawzi did may improve performance: http://dsource.org/projects/tango/browser/trunk/user/tango/core/Lifetime.d?rev=5100#L158

04/20/10 15:41:34 changed by larsivi

The choice of a different malloc (and other optimizations) seems independent from the actual functionality here, as long as it is correct.

04/24/10 18:23:16 changed by kris

  • status changed from new to closed.
  • resolution set to fixed.

weakref is in. WeakHashMap is not