user: Translate the below assembly code into C programming language:

```asm
<test_cgcore_no_internal_process_constraint_on_threads>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x30,%rsp
  mov    %rdi,-0x28(%rbp)
  movl   $0x1,-0x14(%rbp)
  movq   $0x0,-0x10(%rbp)
  movq   $0x0,-0x8(%rbp)
  mov    -0x28(%rbp),%rax
  lea    D20(%rip),%rdx
  lea    D91(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <cg_read_strstr@plt>
  test   %rax,%rax
  jne    L79
  mov    -0x28(%rbp),%rax
  lea    D44(%rip),%rdx
  lea    D0(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <cg_write@plt>
  test   %rax,%rax
  je     L128
L79:
  movl   $0x4,-0x14(%rbp)
  jmp    L34
L128:
  mov    -0x28(%rbp),%rax
  lea    D16(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <cg_name@plt>
  mov    %rax,-0x10(%rbp)
  mov    -0x28(%rbp),%rax
  lea    D6(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <cg_name@plt>
  mov    %rax,-0x8(%rbp)
  cmpq   $0x0,-0x10(%rbp)
  je     L130
  cmpq   $0x0,-0x8(%rbp)
  je     L130
  mov    -0x10(%rbp),%rax
  mov    %rax,%rdi
  call   <cg_create@plt>
  test   %rax,%rax
  jne    L51
  mov    -0x8(%rbp),%rax
  mov    %rax,%rdi
  call   <cg_create@plt>
  test   %rax,%rax
  jne    L154
  mov    -0x10(%rbp),%rax
  lea    D103(%rip),%rdx
  lea    D53(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <cg_write@plt>
  test   %rax,%rax
  jne    L14
  mov    -0x8(%rbp),%rax
  lea    D103(%rip),%rdx
  lea    D53(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <cg_write@plt>
  test   %rax,%rax
  jne    L139
  mov    -0x10(%rbp),%rax
  lea    D44(%rip),%rdx
  lea    D0(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <cg_write@plt>
  test   %rax,%rax
  jne    L197
  mov    -0x10(%rbp),%rax
  mov    %rax,%rdi
  call   <cg_enter_current@plt>
  test   %rax,%rax
  jne    L101
  movl   $0x0,-0x14(%rbp)
  jmp    L34
L130:
  nop
  jmp    L34
L51:
  nop
  jmp    L34
L154:
  nop
  jmp    L34
L14:
  nop
  jmp    L34
L139:
  nop
  jmp    L34
L197:
  nop
  jmp    L34
L101:
  nop
L34:
  mov    -0x28(%rbp),%rax
  mov    %rax,%rdi
  call   <cg_enter_current@plt>
  mov    -0x28(%rbp),%rax
  mov    %rax,%rdi
  call   <cg_enter_current@plt>
  cmpq   $0x0,-0x8(%rbp)
  je     L48
  mov    -0x8(%rbp),%rax
  mov    %rax,%rdi
  call   <cg_destroy@plt>
L48:
  cmpq   $0x0,-0x10(%rbp)
  je     L61
  mov    -0x10(%rbp),%rax
  mov    %rax,%rdi
  call   <cg_destroy@plt>
L61:
  mov    -0x8(%rbp),%rax
  mov    %rax,%rdi
  call   <free@plt>
  mov    -0x10(%rbp),%rax
  mov    %rax,%rdi
  call   <free@plt>
  mov    -0x14(%rbp),%eax
  leave
  ret
```

tool_calls: name: retrieve_data
arguments: label: D20
type_guessed: string
name: retrieve_data
arguments: label: D91
type_guessed: string
name: retrieve_data
arguments: label: D44
type_guessed: string
name: retrieve_data
arguments: label: D0
type_guessed: string
name: retrieve_data
arguments: label: D16
type_guessed: string
name: retrieve_data
arguments: label: D6
type_guessed: string
name: retrieve_data
arguments: label: D103
type_guessed: string
name: retrieve_data
arguments: label: D53
type_guessed: string

tool: D20: cpu

tool: D91: cgroup.controllers

tool: D44: +cpu

tool: D0: cgroup.subtree_control

tool: D16: cg_test_parent

tool: D6: cg_test_parent/cg_test_child

tool: D103: threaded

tool: D53: cgroup.type

assistant: ```c
int test_cgcore_no_internal_process_constraint_on_threads(const char *root) {
  int ret = 1;
  char *parent = NULL, *child = NULL;
  if (cg_read_strstr(root, "cgroup.controllers", "cpu") || cg_write(root, "cgroup.subtree_control", "+cpu")) {
    ret = 4;
    goto cleanup;
  }
  parent = cg_name(root, "cg_test_parent");
  child = cg_name(root, "cg_test_parent/cg_test_child");
  if (!parent || !child)
    goto cleanup;
  if (cg_create(parent))
    goto cleanup;
  if (cg_create(child))
    goto cleanup;
  if (cg_write(parent, "cgroup.type", "threaded"))
    goto cleanup;
  if (cg_write(child, "cgroup.type", "threaded"))
    goto cleanup;
  if (cg_write(parent, "cgroup.subtree_control", "+cpu"))
    goto cleanup;
  if (cg_enter_current(parent))
    goto cleanup;
  ret = 0;
cleanup:
  cg_enter_current(root);
  cg_enter_current(root);
  if (child)
    cg_destroy(child);
  if (parent)
    cg_destroy(parent);
  free(child);
  free(parent);
  return ret;
}
```