Skip to content

Commit

Permalink
grant_max returns largest possible buffer
Browse files Browse the repository at this point in the history
Resolves jamesmunns#29
  • Loading branch information
sjroe committed Aug 18, 2019
1 parent dfc8d88 commit 2af73c5
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 18 deletions.
48 changes: 48 additions & 0 deletions bbqtest/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,4 +271,52 @@ mod tests {
// Ask for something way too big
assert!(tx.grant(10).is_err());
}

#[test]
fn grant_max_returns_largest_possible_buffer() {
let bb = bbq!(7).unwrap();

// Grant and commit most of the buffer
let wgr = bb.grant(5).unwrap();
bb.commit(5, wgr);

// And release
let rgr = bb.read().unwrap();
assert_eq!(rgr.len(), 5);
bb.release(rgr.len(), rgr);

// Request grant where there is enough room if invert
let wgr = bb.grant_max(3).unwrap();
assert_eq!(wgr.len(), 3);

let bb = bbq!(7).unwrap();

// Grant most of the buffer and commit
let wgr = bb.grant(5).unwrap();
bb.commit(5, wgr);

// And release
let rgr = bb.read().unwrap();
assert_eq!(rgr.len(), 5);
bb.release(rgr.len(), rgr);

// Request grant where inverting returns largest buffer
let wgr = bb.grant_max(6).unwrap();
assert_eq!(wgr.len(), 4);

let bb = bbq!(7).unwrap();

// Grant and commit
let wgr = bb.grant(2).unwrap();
bb.commit(2, wgr);

// And release
let rgr = bb.read().unwrap();
assert_eq!(rgr.len(), 2);
bb.release(rgr.len(), rgr);

// Request grant where not inverting returns largest buffer
let wgr = bb.grant_max(6).unwrap();
assert_eq!(wgr.len(), 5);
}
}
43 changes: 25 additions & 18 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,24 +282,26 @@ impl BBQueue {
// Inverted, no room is available
return Err(Error::InsufficientSize);
}
} else if write + sz <= max {
// Enough space for all in un-inverted case
write
} else if sz < read {
// Enough space for all if invert
0
} else if write == max && read <= 1 {
// No space
return Err(Error::InsufficientSize);
} else {
if write != max {
// Some (or all) room remaining in un-inverted case
sz = min(max - write, sz);
// Not enough space for all, choose largest option
let non_inv_sz = max - write;
let inv_sz = if read == 0 { 0 } else { read - 1 };

if non_inv_sz >= inv_sz {
sz = non_inv_sz;
write
} else {
// Not inverted, but need to go inverted

// NOTE: We check read > 1, NOT read >= 1, because
// write must never == read in an inverted condition, since
// we will then not be able to tell if we are inverted or not
if read > 1 {
sz = min(read - 1, sz);
0
} else {
// Not invertible, no space
return Err(Error::InsufficientSize);
}
sz = inv_sz;
0
}
};

Expand All @@ -309,10 +311,15 @@ impl BBQueue {
let c = unsafe { self.buf.as_mut().as_mut_ptr() };
let d = unsafe { from_raw_parts_mut(c, max) };


Ok(GrantW {
let grant = GrantW {
buf: &mut d[start..self.reserve.load(Relaxed)],
})
};

if !self.is_our_grant(&grant.buf) {
panic!("{} {}", sz, start);
}

Ok(grant)
}

/// Finalizes a writable grant given by `grant()` or `grant_max()`.
Expand Down

0 comments on commit 2af73c5

Please sign in to comment.