How to specify lifetime for Global allocated memory

  pub fn new(key: K, val: V) -> &Node<K, V> {
        let node_layout = Layout::new::<Node<K, V>>();
        let string_layout = Layout::new::<V>();
        let alloc: *mut u8 = unsafe {
            match Global.alloc(node_layout) {
                Ok(byte) => byte.as_ptr(),
                Err(_e) => panic!("not able to allocate da"),
            }
        };
        let string_alloc: *mut u8 = unsafe {
            match Global.alloc(string_layout) {
                Ok(byte) => byte.as_ptr(),
                Err(_e) => panic!("not able to allocate da"),
            }
        };
        let node = alloc as *mut Node<K, V>;
        let value = string_alloc as *mut V;
        unsafe {
            *value = val;
        }
        unsafe {
            (*node).key = key;
            (*node).value = AtomicUsize::new(value as usize);
            (*node).lanes = mem::zeroed();
        }
        unsafe { mem::transmute(node) }
    }

I want to return the reference of node.
How to do that?

pub fn new(key: K, val: V) -> &'static Node<K, V> 

I want to dealloc after I use. Is it possible to dealloc the static references?

I take it you've registered your own global allocator? If so, can't you just allocate the node using a Box and let the box deallocate when it goes away?

Or taking a step back, what are you trying to do here? :slight_smile:

Actually I'm writing a concurrent skiplist. I'm just a newbiee tryin to explore rust.
Box memory will be dropped right? when it goes out of scope.

Ok, so it sounds like you don't need to use the allocator directly then?

If you want to allocate memory on the heap, using the default std allocator, then you can use Box::new(). If you want to get the raw ptr to that memory and tell the Box to give up ownership, you can use Box::into_raw. When you're ready to drop the allocation, you do that via Box again, e.g.:

// create a `Box` that's immediately dropped, which deallocs
let _ = Box::from_raw(your_raw_ptr);

If you don't want to work with raw ptrs but do need a heap allocated value, then you can move the Box around - it'll drop normally, whenever it goes out of scope (presumably because the value its embedded in goes away).

Alternatively, you might be able to just move the Node<K,V> around, without putting it on the heap (i.e. boxing it). But I can't say for sure - it depends on how you implement things. If you plan on storing raw ptrs, however, then you'll almost certainly want to put the value on the heap so you don't accidentally hold a raw ptr to a stack value that gets destroyed/moved/etc.

1 Like

Thanks, It is really helpful. Once I done with the skiplist, I'll update here. :slight_smile:

I just tried with phantomdata. it is working fine. but I'm not sure whether it is idiomatic way or not

   pub fn new(key: K, val: V, _phantom_data: &PhantomData<V>) -> &Node<K, V> {
        let node_layout = Layout::new::<Node<K, V>>();
        let string_layout = Layout::new::<V>();
        let alloc: *mut u8 = unsafe {
            match Global.alloc(node_layout) {
                Ok(byte) => byte.as_ptr(),
                Err(_e) => panic!("not able to allocate da"),
            }
        };
        let string_alloc: *mut u8 = unsafe {
            match Global.alloc(string_layout) {
                Ok(byte) => byte.as_ptr(),
                Err(_e) => panic!("not able to allocate da"),
            }
        };
        let node = alloc as *mut Node<K, V>;
        let value = string_alloc as *mut V;
        unsafe {
            *value = val;
        }
        unsafe {
            (*node).key = key;
            (*node).value = AtomicUsize::new(value as usize);
            (*node).lanes = mem::zeroed();
        }
        unsafe { mem::transmute(node) }
    }

No, it's not idiomatic for this :slight_smile:. Since you're new to Rust, I suggest putting the concurrent skiplist project on the backburner and focus on familiarizing yourself with the basics of Rust first, starting with simpler little exercises.

2 Likes