Skip to content

Instantly share code, notes, and snippets.

Created July 25, 2009 20:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/154958 to your computer and use it in GitHub Desktop.
Save anonymous/154958 to your computer and use it in GitHub Desktop.
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) ;
}
/*
* 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()) ;
}
}
/*==========================================================================
* 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