#Am I using std.atomic.Queue wrong?

1 messages · Page 1 of 1 (latest)

dawn jackal
#

I've just realized std.atomic.Queue is either exhibiting extremely buggy behavior, or I'm using it in a wildly incorrect way.

I would expect the following to print 0 to 9, but it actually prints just the last item in the queue:

const std = @import("std");                                                     
                                                                                
pub fn main() !void {                                                           
    var q = std.atomic.Queue(usize).init();                                     
                                                                                
    var i: usize = 0;                                                           
    while (i < 10) : (i += 1) {                                                 
        var d = .{ .data = i };                                                 
        q.put(&d);                                                              
    }                                                                           
                                                                                
    while (q.get()) |x| {                                                       
        std.debug.print("{} {}\n", .{ x, q.isEmpty() });                        
    }                                                                           
}  

output:

$ zig run test.zig 
linked_list.TailQueue(usize).Node{ .prev = null, .next = null, .data = 9 } false
linked_list.TailQueue(usize).Node{ .prev = null, .next = null, .data = 9 } true

q.dump indicates it's looping around to the same element:

head: 0x7ffcb30bcab0=9
 0x7ffcb30bcab0=9
  0x7ffcb30bcab0=9
   0x7ffcb30bcab0=9
    0x7ffcb30bcab0=9
(max depth)
tail: 0x7ffcb30bcab0=9
 0x7ffcb30bcab0=9
  0x7ffcb30bcab0=9
   0x7ffcb30bcab0=9
    0x7ffcb30bcab0=9
(max depth)

Even better, I can get a segfault (on both 0.10 and master) if I change .data = i to .data = 0. Is this a known issue?

#

oh wait

#

i probably have to allocate it on the heap huh

stoic kayak
#

^^^

gilded peak
#

atomic.Queue is intrusive (think linked list) It means the caller has to guarantee the memory is valid for each item

var d = .{ .data = i };                                                 
q.put(&d); 

This invalidates it on each iteration