// File: /workspace/github_c_makefile_star2_O0/FH0[P]tun_direct/lwip-2.1.2/src/core/pbuf.c
// Function: pbuf_free
u8_t
pbuf_free(struct pbuf *p)
{
  u8_t alloc_src;
  struct pbuf *q;
  u8_t count;

  if (p == NULL) {
    LWIP_ASSERT("p != NULL", p != NULL);
    /* if assertions are disabled, proceed with debug output */
    LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
                ("pbuf_free(p == NULL) was called.\n"));
    return 0;
  }
  LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free(%p)\n", (void *)p));

  PERF_START;

  count = 0;
  /* de-allocate all consecutive pbufs from the head of the chain that
   * obtain a zero reference count after decrementing*/
  while (p != NULL) {
    LWIP_PBUF_REF_T ref;
    SYS_ARCH_DECL_PROTECT(old_level);
    /* Since decrementing ref cannot be guaranteed to be a single machine operation
     * we must protect it. We put the new ref into a local variable to prevent
     * further protection. */
    SYS_ARCH_PROTECT(old_level);
    /* all pbufs in a chain are referenced at least once */
    LWIP_ASSERT("pbuf_free: p->ref > 0", p->ref > 0);
    /* decrease reference count (number of pointers to pbuf) */
    ref = --(p->ref);
    SYS_ARCH_UNPROTECT(old_level);
    /* this pbuf is no longer referenced to? */
    if (ref == 0) {
      /* remember next pbuf in chain for next iteration */
      q = p->next;
      LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: deallocating %p\n", (void *)p));
      alloc_src = pbuf_get_allocsrc(p);
#if LWIP_SUPPORT_CUSTOM_PBUF
      /* is this a custom pbuf? */
      if ((p->flags & PBUF_FLAG_IS_CUSTOM) != 0) {
        struct pbuf_custom *pc = (struct pbuf_custom *)p;
        LWIP_ASSERT("pc->custom_free_function != NULL", pc->custom_free_function != NULL);
        pc->custom_free_function(p);
      } else
#endif /* LWIP_SUPPORT_CUSTOM_PBUF */
      {
        /* is this a pbuf from the pool? */
        if (alloc_src == PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF_POOL) {
          memp_free(MEMP_PBUF_POOL, p);
          /* is this a ROM or RAM referencing pbuf? */
        } else if (alloc_src == PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF) {
          memp_free(MEMP_PBUF, p);
          /* type == PBUF_RAM */
        } else if (alloc_src == PBUF_TYPE_ALLOC_SRC_MASK_STD_HEAP) {
          mem_free(p);
        } else {
          /* @todo: support freeing other types */
          LWIP_ASSERT("invalid pbuf type", 0);
        }
      }
      count++;
      /* proceed to next pbuf */
      p = q;
      /* p->ref > 0, this pbuf is still referenced to */
      /* (and so the remaining pbufs in chain as well) */
    } else {
      LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: %p has ref %"U16_F", ending here.\n", (void *)p, (u16_t)ref));
      /* stop walking through the chain */
      p = NULL;
    }
  }
  PERF_STOP("pbuf_free");
  /* return number of de-allocated pbufs */
  return count;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0x72bc
jmp 0x7275
cmpq $0x0, -0x10(%rbp)
jne 0x72ad
jmp 0x727e
leaq 0x20047(%rip), %rdi     # 0x272cc
leaq 0x206d2(%rip), %rsi     # 0x2795e
movl $0x2dc, %edx            # imm = 0x2DC
leaq 0x20611(%rip), %rcx     # 0x278a9
movb $0x0, %al
callq 0x20d0
xorl %eax, %eax
movl %eax, %edi
callq 0x21b0
callq 0x2040
jmp 0x72af
jmp 0x72b1
jmp 0x72b3
movb $0x0, -0x1(%rbp)
jmp 0x7456
jmp 0x72be
jmp 0x72c0
movb $0x0, -0x21(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x7450
jmp 0x72d1
movq -0x10(%rbp), %rax
movzbl 0x16(%rax), %eax
cmpl $0x0, %eax
jg 0x730f
jmp 0x72e0
leaq 0x1ffe5(%rip), %rdi     # 0x272cc
leaq 0x206cc(%rip), %rsi     # 0x279ba
movl $0x2f1, %edx            # imm = 0x2F1
leaq 0x205af(%rip), %rcx     # 0x278a9
movb $0x0, %al
callq 0x20d0
xorl %eax, %eax
movl %eax, %edi
callq 0x21b0
callq 0x2040
jmp 0x7311
movq -0x10(%rbp), %rcx
movb 0x16(%rcx), %al
addb $-0x1, %al
movb %al, 0x16(%rcx)
movb %al, -0x22(%rbp)
movzbl -0x22(%rbp), %eax
cmpl $0x0, %eax
jne 0x743f
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x20(%rbp)
jmp 0x733a
movq -0x10(%rbp), %rax
movzbl 0x14(%rax), %eax
andl $0xf, %eax
movb %al, -0x11(%rbp)
movq -0x10(%rbp), %rax
movzbl 0x15(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x73ae
movq -0x10(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpq $0x0, 0x18(%rax)
jne 0x739c
jmp 0x736d
leaq 0x1ff58(%rip), %rdi     # 0x272cc
leaq 0x20655(%rip), %rsi     # 0x279d0
movl $0x2ff, %edx            # imm = 0x2FF
leaq 0x20522(%rip), %rcx     # 0x278a9
movb $0x0, %al
callq 0x20d0
xorl %eax, %eax
movl %eax, %edi
callq 0x21b0
callq 0x2040
jmp 0x739e
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x10(%rbp), %rdi
callq *%rax
jmp 0x742d
movzbl -0x11(%rbp), %eax
cmpl $0x2, %eax
jne 0x73c7
movq -0x10(%rbp), %rsi
movl $0xb, %edi
callq 0x4a80
jmp 0x742b
movzbl -0x11(%rbp), %eax
cmpl $0x1, %eax
jne 0x73e0
movq -0x10(%rbp), %rsi
movl $0xa, %edi
callq 0x4a80
jmp 0x7429
movzbl -0x11(%rbp), %eax
cmpl $0x0, %eax
jne 0x73f4
movq -0x10(%rbp), %rdi
callq 0x46e0
jmp 0x7427
jmp 0x73f6
jmp 0x73f8
leaq 0x1fecd(%rip), %rdi     # 0x272cc
leaq 0x205eb(%rip), %rsi     # 0x279f1
movl $0x30f, %edx            # imm = 0x30F
leaq 0x20497(%rip), %rcx     # 0x278a9
movb $0x0, %al
callq 0x20d0
xorl %eax, %eax
movl %eax, %edi
callq 0x21b0
callq 0x2040
jmp 0x7429
jmp 0x742b
jmp 0x742d
movb -0x21(%rbp), %al
addb $0x1, %al
movb %al, -0x21(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x10(%rbp)
jmp 0x744b
jmp 0x7441
jmp 0x7443
movq $0x0, -0x10(%rbp)
jmp 0x72c4
movb -0x21(%rbp), %al
movb %al, -0x1(%rbp)
movb -0x1(%rbp), %al
addq $0x30, %rsp
popq %rbp
retq
nop