1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
16 static RC_IMMORTAL : uint = 0x77777777;
21 * This runs at task death to free all boxes.
24 unsafe fn each_live_alloc(read_next_before: bool,
25 f: |alloc: *mut raw::Box<()>| -> bool)
27 //! Walks the internal list of allocations
31 let mut alloc = local_heap::live_allocs();
32 while alloc != ptr::mut_null() {
33 let next_before = (*alloc).next;
42 alloc = (*alloc).next;
49 fn debug_mem() -> bool {
50 // FIXME: Need to port the environment struct to newsched
55 fn debug_mem() -> bool {
59 /// Destroys all managed memory (i.e. @ boxes) held by the current task.
60 pub unsafe fn annihilate() {
61 use rt::local_heap::local_free;
63 let mut n_total_boxes = 0u;
65 // Pass 1: Make all boxes immortal.
67 // In this pass, nothing gets freed, so it does not matter whether
68 // we read the next field before or after the callback.
69 each_live_alloc(true, |alloc| {
71 (*alloc).ref_count = RC_IMMORTAL;
75 // Pass 2: Drop all boxes.
77 // In this pass, unique-managed boxes may get freed, but not
78 // managed boxes, so we must read the `next` field *after* the
79 // callback, as the original value may have been freed.
80 each_live_alloc(false, |alloc| {
81 let drop_glue = (*alloc).drop_glue;
82 let data = &mut (*alloc).data as *mut ();
83 drop_glue(data as *mut u8);
87 // Pass 3: Free all boxes.
89 // In this pass, managed boxes may get freed (but not
90 // unique-managed boxes, though I think that none of those are
91 // left), so we must read the `next` field before, since it will
92 // not be valid after.
93 each_live_alloc(true, |alloc| {
94 local_free(alloc as *u8);
99 // We do logging here w/o allocation.
100 println!("total boxes annihilated: {}", n_total_boxes);