Created
July 25, 2009 20:35
-
-
Save anonymous/154958 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import std.stdio ; | |
import std.string ; | |
import std.conv ; | |
import std.math ; | |
import std.stdint ; | |
import core.memory ; | |
import std.random ; | |
import weakref ; | |
class AllocationItem | |
{ | |
int value ; | |
AllocationItem a1, a2, a3 ; | |
this(int v) | |
{ | |
value = v ; | |
} | |
} ; | |
void RunAllocations () | |
{ | |
const int n_items = 10 ; | |
const int n_iters = 1000 ; | |
WeakRef!(AllocationItem)[] w_items ; | |
AllocationItem [n_items] items ; | |
AllocationItem get_item (AllocationItem s) | |
{ | |
AllocationItem a ; | |
do | |
{ | |
a = w_items [my_rand (w_items.length)].ptr ; | |
} | |
while (a is null || a is s) ; | |
return a ; | |
} | |
int sum1, sum2 ; | |
foreach (i; 0 .. n_items) | |
{ | |
items [i] = new AllocationItem(0) ; | |
w_items ~= new WeakRef!(AllocationItem)(items [i]) ; | |
} | |
foreach (a; items) | |
{ | |
a.a1 = get_item (a) ; | |
a.a2 = get_item (a) ; | |
a.a3 = get_item (a) ; | |
} | |
foreach (i; 0 .. n_iters) | |
{ | |
uint q = my_rand (n_items) ; | |
AllocationItem a = new AllocationItem (1) ; | |
items [q] = a ; | |
bool not_empty = true ; | |
foreach (ref w; w_items) | |
{ | |
if (w.ptr is null) | |
{ | |
w = new WeakRef!(AllocationItem)(a) ; | |
not_empty = false ; | |
break ; | |
} | |
} | |
if (not_empty) | |
w_items ~= new WeakRef!(AllocationItem)(a) ; | |
a.a1 = get_item (a) ; | |
a.a2 = get_item (a) ; | |
a.a3 = get_item (a) ; | |
a = get_item (null) ; | |
a.a1 = get_item (a) ; | |
//a.a1 = null ; | |
a = get_item (null) ; | |
a.a2 = get_item (a) ; | |
//a.a2 = null ; | |
a = get_item (null) ; | |
a.a3 = get_item (a) ; | |
//a.a3 = null ; | |
GC.collect ; | |
} | |
foreach (w; w_items) | |
{ | |
if (w.ptr) | |
{ | |
if (!w.ptr.value) | |
++ sum1 ; | |
else | |
++ sum2 ; | |
} | |
} | |
printf("OLD: %d\n" | |
"NEW: %d\n", sum1, sum2) ; | |
} | |
int main(char[][] args) | |
{ | |
RunAllocations ; | |
return 0; | |
} | |
uint32_t my_rand_0 () | |
{ | |
const uint32_t a = 1664525 ; | |
const uint32_t c = 1013904223 ; | |
static uint32_t x = 0 ; | |
x = a * x + c ; | |
return x ; | |
} | |
unittest | |
{ | |
uint32_t res [11] = [ 0x3C6EF35F, 0x47502932, 0xD1CCF6E9, 0xAAF95334, | |
0x6252E503, 0x9F2EC686, 0x57FE6C2D, 0xA3D95FA8, | |
0x81FDBEE7, 0x94F0AF1A, 0xCBF633B1 ] ; | |
for (int i = 0 ; i < 11 ; ++i) | |
assert (res [i] == my_rand_0 ()) ; | |
} | |
uint my_rand (uint val) | |
{ | |
// changed that to be like in java | |
//return cast(uint)(floor (cast(real)my_rand_0*val/(uint.max+1.0))) ; | |
// changed to java equivalent | |
static if (0) | |
{ | |
const double uint_32 = pow (2.0, 32) ; | |
double t = my_rand_0 () ; | |
if (t < 0) | |
t = uint_32 + t ; | |
return cast(uint)floor (t*val / uint_32 ) ; | |
} | |
// changed to library standard, as java made so for speed up | |
else | |
{ | |
static Mt19937 r ; | |
r.popFront ; | |
return cast(uint) floor(cast(real)val * r.front / (uint.max + 1.0)) ; | |
} | |
} | |
unittest | |
{ | |
for (int i = 1 ; i < 100_000; ++i) | |
assert (my_rand(100) < 100) ; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* To change this template, choose Tools | Templates | |
* and open the template in the editor. | |
*/ | |
package test_gc; | |
//import java.lang.ref.WeakReference; | |
import java.lang.ref.*; | |
//import java.util.*; | |
/** | |
* | |
* @author Admin | |
*/ | |
class AllocationItem | |
{ | |
int value ; | |
AllocationItem a1, a2, a3 ; | |
AllocationItem(int v) | |
{ | |
value = v ; | |
} | |
} ; | |
public class Main | |
{ | |
private static int n_items = 10 ; | |
private static int n_iters = 100 ; | |
private static WeakReference [] w_items = new WeakReference [n_iters+n_items] ; | |
private static int w_count = 0 ; | |
public static void main (String[] args) | |
{ | |
RunAllocations (); | |
} | |
private static void RunAllocations () | |
{ | |
AllocationItem [] items = new AllocationItem [n_items] ; | |
int sum1 = 0, sum2 = 0 ; | |
for (int i = 0; i < n_items; ++i) | |
{ | |
items [i] = new AllocationItem(0) ; | |
w_items [w_count] = new WeakReference<AllocationItem> (items [i]) ; | |
++w_count ; | |
} | |
for (int i = 0; i < n_items; ++i) | |
{ | |
AllocationItem a = items [i] ; | |
a.a1 = get_item (a) ; | |
a.a2 = get_item (a) ; | |
a.a3 = get_item (a) ; | |
} | |
for (int i = 0; i < n_iters; ++i) | |
{ | |
int q = my_rand (n_items) ; | |
AllocationItem a = new AllocationItem (1) ; | |
items [q] = a ; | |
boolean not_empty = true ; | |
for (i = 0; i < w_count; ++i) | |
{ | |
if (w_items [i].get () == null) | |
{ | |
w_items [i] = new WeakReference<AllocationItem> (a) ; | |
not_empty = false ; | |
break ; | |
} | |
} | |
if (not_empty) | |
{ | |
w_items [w_count] = new WeakReference<AllocationItem> (a) ; | |
++w_count ; | |
} | |
a.a1 = get_item (a) ; | |
a.a2 = get_item (a) ; | |
a.a3 = get_item (a) ; | |
a = get_item (null) ; | |
a.a1 = get_item (a) ; | |
// when commenting upline and downcommenting downline java work horribly slow | |
//a.a1 = null ; | |
a = get_item (null) ; | |
a.a2 = get_item (a) ; | |
//a.a1 = null ; | |
a = get_item (null) ; | |
a.a3 = get_item (a) ; | |
//a.a1 = null ; | |
System.gc () ; | |
} | |
for (int i = 0; i < w_count; ++i) | |
{ | |
AllocationItem a =(AllocationItem)w_items [i].get () ; | |
if (a != null) | |
{ | |
if (a.value == 0) | |
++ sum1 ; | |
else | |
++ sum2 ; | |
} | |
} | |
// printf("OLD: %d\n" | |
// "NEW: %d\n", sum1, sum2) ; | |
System.out.println ("OLD: " + sum1 + "\n" + "NEW: " + sum2) ; | |
} | |
private static AllocationItem get_item (AllocationItem s) | |
{ | |
AllocationItem a ; | |
do | |
{ | |
a = (AllocationItem) w_items [my_rand (w_count)].get () ; | |
} | |
while (a == null || a == s) ; | |
return a ; | |
} | |
static int my_rand_0_x = 0 ; | |
private static int my_rand_0 () | |
{ | |
int a = 1664525 ; | |
int c = 1013904223 ; | |
//static int x = 0 ; | |
my_rand_0_x = a * my_rand_0_x + c ; | |
return my_rand_0_x ; | |
} | |
static double uint_32 = Math.pow (2, 32) ; | |
//static double uint_31 = Math.pow (2, 31) ; | |
private static int my_rand (int val) | |
{ | |
// made for speed up :) | |
/* | |
double t = my_rand_0 () ; | |
if (t < 0) | |
t = uint_32 + t ; | |
return (int)Math.floor (t*val / uint_32 ) ; | |
*/ | |
return (int)Math.floor(val * Math.random()) ; | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*========================================================================== | |
* weakref.d | |
* Written in the D Programming Language (http://www.digitalmars.com/d) | |
*/ | |
/*************************************************************************** | |
* Creates a weak reference to a class instance. | |
* | |
* A weak reference lets you hold onto a pointer to an object without | |
* preventing the garbage collector from collecting it. | |
* If the garbage collector collects the object then the weak pointer will | |
* become 'null'. Thus one should always check a weak pointer for null | |
* before doing anything that depends upon it having a value. | |
* | |
* Tested with: | |
* DMD 1.025 / Phobos 1.025 | |
* DMD 1.025 / Tango 0.99.4 | |
* | |
* Usage example: | |
--- | |
class Something {} | |
auto a = new Something(); | |
auto wa = new WeakRef!(Something)(a); | |
std.gc.fullCollect(); | |
// Reference 'a' prevents collection so wa.ptr is non-null | |
assert(wa.ptr is a); | |
delete a; | |
// 'a' is gone now, so wa.ptr magically becomes null | |
assert(wa.ptr is null); | |
--- | |
* | |
* | |
* Author: William V. Baxter III | |
* Contributors: | |
* Date: 21 Jan 2008 | |
* Copyright: (C) 2008 William Baxter | |
* License: Public Domain where allowed by law, ZLIB/PNG otherwise. | |
*/ | |
//=========================================================================== | |
// ! Modidied for D2 usage only | |
module weakref; | |
private { | |
alias void delegate(Object) DisposeEvt; | |
extern (C) void rt_attachDisposeEvent( Object obj, DisposeEvt evt ); | |
extern (C) void rt_detachDisposeEvent( Object obj, DisposeEvt evt ); | |
} | |
class WeakRef(T : Object) { | |
private: | |
size_t cast_ptr_; | |
void unhook(Object o) { | |
if (cast(size_t)cast(void*)o == cast_ptr_) { | |
rt_detachDisposeEvent(o, &unhook); | |
cast_ptr_ = 0; | |
} | |
} | |
public: | |
this(T tptr) { | |
cast_ptr_ = cast(size_t)cast(void*)tptr; | |
rt_attachDisposeEvent(tptr, &unhook); | |
} | |
~this() { | |
T p = ptr(); | |
if (p) { | |
rt_detachDisposeEvent(p, &unhook); | |
} | |
} | |
T ptr() { | |
return cast(T)cast(void*)cast_ptr_; | |
} | |
WeakRef dup() { | |
return new WeakRef(ptr()); | |
} | |
} | |
// import core.memory ; | |
unittest { | |
class Something { | |
int value; | |
this(int v) { value = v; } | |
~this() { value = -1; } | |
} | |
WeakRef!(Something) wa; | |
auto a = new Something(1); | |
wa = new WeakRef!(Something)(a); | |
assert(a is wa.ptr); | |
GC.collect(); | |
assert(a is wa.ptr); | |
delete a; | |
// a now gone so should be collected | |
GC.collect(); | |
assert(wa.ptr is null); | |
} | |
//--- Emacs setup --- | |
// Local Variables: | |
// c-basic-offset: 4 | |
// indent-tabs-mode: nil | |
// End: | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment