// File: /workspace/github_c_makefile_star2_O3/Tarsnap[P]kivaloo/lbs-s3/deleteto.c
// Function: poke
static int
poke(struct deleteto * D)
{
	uint64_t BIT;
	uint64_t X;
	uint8_t DeletedMarker[8];

	/* If we're trying to shut down, don't do anything. */
	if (D->shuttingdown)
		return (0);

	/* If operations are already in progress, don't do anything. */
	if (! D->idle)
		return (0);

	/* Sanity-check. */
	assert(D->npending == 0);

	/*
	 * Store the M to object DeletedMarker if it's a multiple of 256
	 * (periodic stores so DeletedMarker doesn't fall too far behind
	 * reality if we are doing a very large number of deletes) and we
	 * haven't yet stored this value of M.
	 *
	 * If we crash and restart, we may end up re-issuing as many as ~256
	 * deletes; but this is better than more-frequent updating of the
	 * deletion marker since (a) DELETEs are free but PUTs aren't, and
	 * (b) we want to optimize for the common case, which is a long-lived
	 * lbs-s3 process.
	 */
	if ((D->M % 256 == 0) && (D->updateDeletedTo == 1)) {
		D->idle = 0;
		D->npending += 1;
		be64enc(DeletedMarker, D->M);
		if (proto_s3_request_put(D->Q, D->bucket, "DeletedMarker",
		    8, DeletedMarker, callback_done, D))
			goto err0;
		D->updateDeletedTo = 0;
	}

	/* If we can't delete anything, don't. */
	if (D->N <= D->M)
		return (0);

	/*
	 * We want to run one step of the DeleteTo algorithm: Delete or
	 * overwrite objects which are needed by M but not by M+1, and
	 * increment M.  If nothing needs to be done, we'll repeat the
	 * process for the new (incremented) M.
	 */

	/* For each bit... */
	for (BIT = 1; BIT != 0; BIT += BIT) {
		/* If it's set in M but not in M+1... */
		if (((D->M & BIT) == BIT) &&
		    (((D->M + 1) & BIT) == 0)) {
			/* M - M % BIT is deletable... */
			X = D->M - (D->M % BIT);

			/* ... unless it's a power of two. */
			if (X == BIT)
				continue;

			/* Issue a delete. */
			D->idle = 0;
			D->npending += 1;
			if (proto_s3_request_delete(D->Q, D->bucket,
			    objmap(X), callback_done, D))
				goto err0;
		}
	}

	/*
	 * Powers of 2 will never be DELETEd, and multiples of 256 can't be
	 * deleted until at least 256 iterations later (since N = ...abcdefgh)
	 * needs the file ...00000000 to still exist), but we don't need the
	 * data for M any more; so issue an empty PUT for it if it falls into
	 * one of those two categories.
	 */
	if (((D->M & (D->M-1)) == 0) || ((D->M % 256) == 0)) {
		D->idle = 0;
		D->npending += 1;
		if (proto_s3_request_put(D->Q, D->bucket, objmap(D->M),
		    0, NULL, callback_done, D))
			goto err0;
	}

	/* We've issued all the deletes needed for this M. */
	D->M = D->M + 1;
	D->updateDeletedTo = 1;

	/* If we haven't found anything to do yet, poke ourselves again. */
	if (D->idle)
		return (poke(D));

	/* Success! */
	return (0);

err0:
	/* Failure! */
	return (-1);
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x10, %rsp
cmpl $0x0, 0x38(%rdi)
je 0x3f2e
xorl %eax, %eax
addq $0x10, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
movq %rdi, %rbx
cmpl $0x0, 0x30(%rdi)
je 0x3f1e
cmpq $0x0, 0x28(%rbx)
jne 0x40f5
movq 0x18(%rbx), %rax
testb %al, %al
jne 0x3fec
cmpl $0x1, 0x34(%rbx)
jne 0x3fec
movl $0x0, 0x30(%rbx)
movq $0x1, 0x28(%rbx)
leaq 0x8(%rsp), %r8
movb $0x0, 0x7(%r8)
movb %ah, 0xe(%rsp)
movl %eax, %ecx
shrl $0x10, %ecx
movb %cl, 0x5(%r8)
movl %eax, %ecx
shrl $0x18, %ecx
movb %cl, 0x4(%r8)
movq %rax, %rcx
shrq $0x20, %rcx
movb %cl, 0x3(%r8)
movq %rax, %rcx
shrq $0x28, %rcx
movb %cl, 0x2(%r8)
movq %rax, %rcx
shrq $0x30, %rcx
movb %cl, 0x1(%r8)
shrq $0x38, %rax
movb %al, (%r8)
movq (%rbx), %rdi
movq 0x8(%rbx), %rsi
movq %rbx, (%rsp)
leaq 0x9641(%rip), %rdx      # 0xd602
leaq 0x17e(%rip), %r9        # 0x4146
movl $0x8, %ecx
callq 0x9f04
movl %eax, %ecx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
testl %ecx, %ecx
jne 0x3f20
movl $0x0, 0x34(%rbx)
movq 0x18(%rbx), %rax
cmpq %rax, 0x10(%rbx)
jbe 0x3f1e
movl $0x1, %r13d
leaq 0x143(%rip), %r14       # 0x4146
movq 0x18(%rbx), %rdi
movq %rdi, %rax
notq %rax
testq %rax, %r13
jne 0x405c
leaq 0x1(%rdi), %rax
testq %r13, %rax
jne 0x405c
movq %r13, %rax
negq %rax
andq %rax, %rdi
cmpq %r13, %rdi
je 0x405c
movl $0x0, 0x30(%rbx)
incq 0x28(%rbx)
movq (%rbx), %r15
movq 0x8(%rbx), %r12
callq 0x4400
movq %r15, %rdi
movq %r12, %rsi
movq %rax, %rdx
movq %r14, %rcx
movq %rbx, %r8
callq 0xa8ce
testl %eax, %eax
jne 0x40eb
addq %r13, %r13
jne 0x4003
movq 0x18(%rbx), %rdi
leaq -0x1(%rdi), %rax
testq %rax, %rdi
setne %al
testb %dil, %dil
setne %cl
testb %cl, %al
jne 0x40c1
movl $0x0, 0x30(%rbx)
incq 0x28(%rbx)
movq (%rbx), %r14
movq 0x8(%rbx), %r15
callq 0x4400
movq %rbx, (%rsp)
leaq 0xab(%rip), %r9         # 0x4146
movq %r14, %rdi
movq %r15, %rsi
movq %rax, %rdx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x9f04
movl %eax, %ecx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
testl %ecx, %ecx
jne 0x3f20
movq 0x18(%rbx), %rdi
incq %rdi
movq %rdi, 0x18(%rbx)
movl $0x1, 0x34(%rbx)
cmpl $0x0, 0x30(%rbx)
movl $0x0, %eax
je 0x3f20
movq %rbx, %rdi
callq 0x3f0b
jmp 0x3f20
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
jmp 0x3f20
leaq 0x9203(%rip), %rdi      # 0xd2ff
leaq 0x9582(%rip), %rsi      # 0xd685
leaq 0x9586(%rip), %rcx      # 0xd690
movl $0xa8, %edx
callq 0x21a0