// File: UTSASRG[P]Guarder/./bibopheap.hh
// Function: BibopHeap::BibopFreeCache::add(void*)
inline bool add(void * addr) {
							// Check if this buffer has reached full capacity...
							if(_numFreeObjects == _capacity) {
									#ifdef USE_GLOBAL_FREE_CACHE
									// Attempt to donate up to half of the
									// local buffer's items to the global buffer
									if(_myGlobalFreeCache) {
											int i;

											_myGlobalFreeCache->acquireLock();
											for(i = 0; i < (_capacity >> 1); i++) {
													if(!_myGlobalFreeCache->add(getNext())) {
															break;
													}
											}
											_myGlobalFreeCache->releaseLock();
											PRDBG("donated %d objects to global cache", i);
											// If i==0, the global free cache is also at full capacity
											if(i == 0) {
													FATAL("global and local free cache out of capacity");
											}
									} else {
											// If we are a global buffer and we're full,
											// simply return false back to the caller
											return false;
									}
									#else
									// If the global free cache is not in use and the local
									// buffer is full, print an error and return false
									PRERR("local free cache out of capacity: dropping object %p", addr);
									return false;
									#endif
							}

							*(void **)_head = addr;
							_head += POINTER_SIZE;
							if(_head == _endaddr) {
									// do wrap-around on _head
									_head = _startaddr;
							}

							_numFreeObjects++;

							/*
							// DEBUG: internal consistency check
							long count = (_endaddr - _startaddr) / sizeof(void *);
							if(_head > _tail) {
									count = (_head - _tail) / sizeof(void *);
							} else if(_head < _tail) {
									count = ((_endaddr - _tail) + (_head - _startaddr)) / sizeof(void *);
							}
							PRDBG("freeCache->add(%p): this=%p, _numFreeObjects=%lu, count=%ld, _capacity=%lu, _start=0x%lx, _end=0x%lx",
											addr, this, _numFreeObjects, count, _capacity, _startaddr, _endaddr);
							if(_numFreeObjects != count) {
									FATAL("freeCache->add(%p): this=%p, _numFreeObjects=%lu, count=%ld, _capacity=%lu, _start=0x%lx, _end=0x%lx",
													addr, this,  _numFreeObjects, count, _capacity, _startaddr, _endaddr);
							}
							*/

							if(_head == _tail) {
									PRDBG("free cache is now full");
									if(_numFreeObjects != _capacity) {
											PRERR("_numFreeObjects = %lu, _capacity = %lu", _numFreeObjects, _capacity);
									}
									assert(_numFreeObjects == _capacity);
							}

							return true;
					}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rcx
movq %rcx, -0x20(%rbp)
movq 0x38(%rcx), %rax
cmpq 0x28(%rcx), %rax
jne 0xad0f
callq 0x52d0
movq %rax, -0x30(%rbp)
callq 0x5400
movq -0x30(%rbp), %rdi
movq %rax, %rcx
movq -0x18(%rbp), %rax
movl $0x1000, %esi           # imm = 0x1000
leaq 0x27dc(%rip), %rdx      # 0xd4a3
leaq 0x1894(%rip), %r8       # 0xc562
movl $0x103, %r9d            # imm = 0x103
movq %rax, (%rsp)
movb $0x0, %al
callq 0x57e0
callq 0x52d0
movq %rax, -0x28(%rbp)
callq 0x52d0
movq %rax, %rdi
callq 0x51e0
movq -0x28(%rbp), %rsi
movq %rax, %rdx
movl $0x2, %edi
callq 0x5160
movb $0x0, -0x1(%rbp)
jmp 0xae6e
movq -0x20(%rbp), %rcx
movq -0x18(%rbp), %rdx
movq 0x18(%rcx), %rax
movq %rdx, (%rax)
movq 0x18(%rcx), %rax
addq $0x8, %rax
movq %rax, 0x18(%rcx)
movq 0x18(%rcx), %rax
cmpq 0x10(%rcx), %rax
jne 0xad40
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rcx
movq %rcx, 0x18(%rax)
movq -0x20(%rbp), %rcx
movq 0x38(%rcx), %rax
addq $0x1, %rax
movq %rax, 0x38(%rcx)
movq 0x18(%rcx), %rax
cmpq 0x20(%rcx), %rax
jne 0xae6a
callq 0x52d0
movq %rax, -0x40(%rbp)
callq 0x5400
movq -0x40(%rbp), %rdi
movq %rax, %rcx
movl $0x1000, %esi           # imm = 0x1000
leaq 0x277d(%rip), %rdx      # 0xd4fc
leaq 0x17dc(%rip), %r8       # 0xc562
movl $0x122, %r9d            # imm = 0x122
movb $0x0, %al
callq 0x57e0
callq 0x52d0
movq %rax, -0x38(%rbp)
callq 0x52d0
movq %rax, %rdi
callq 0x51e0
movq -0x38(%rbp), %rsi
movq %rax, %rdx
movl $0x2, %edi
callq 0x5160
movq -0x20(%rbp), %rcx
movq 0x38(%rcx), %rax
cmpq 0x28(%rcx), %rax
je 0xae39
callq 0x52d0
movq %rax, -0x50(%rbp)
callq 0x5400
movq -0x50(%rbp), %rdi
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq 0x38(%rax), %r10
movq 0x28(%rax), %rax
movl $0x1000, %esi           # imm = 0x1000
leaq 0x273e(%rip), %rdx      # 0xd533
leaq 0x1766(%rip), %r8       # 0xc562
movl $0x124, %r9d            # imm = 0x124
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
movb $0x0, %al
callq 0x57e0
callq 0x52d0
movq %rax, -0x48(%rbp)
callq 0x52d0
movq %rax, %rdi
callq 0x51e0
movq -0x48(%rbp), %rsi
movq %rax, %rdx
movl $0x2, %edi
callq 0x5160
movq -0x20(%rbp), %rcx
movq 0x38(%rcx), %rax
cmpq 0x28(%rcx), %rax
jne 0xae49
jmp 0xae68
leaq 0x272e(%rip), %rdi      # 0xd57e
leaq 0x170b(%rip), %rsi      # 0xc562
movl $0x126, %edx            # imm = 0x126
leaq 0x2738(%rip), %rcx      # 0xd59b
callq 0x5300
jmp 0xae6a
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax)