user: 请将以下的汇编代码转换成C语言代码：

```asm
<test_cgcore_no_internal_process_constraint_on_threads>:
  endbr64
  push   %r15
  lea    D38(%rip),%rdx
  lea    D86(%rip),%rsi
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  mov    %rdi,%rbp
  push   %rbx
  sub    $0x8,%rsp
  call   <cg_read_strstr@plt>
  test   %rax,%rax
  jne    L8
  lea    D23(%rip),%r15
  lea    D84(%rip),%r14
  mov    %rbp,%rdi
  mov    %r15,%rdx
  mov    %r14,%rsi
  call   <cg_write@plt>
  test   %rax,%rax
  jne    L8
  lea    D81(%rip),%rsi
  mov    %rbp,%rdi
  call   <cg_name@plt>
  lea    D18(%rip),%rsi
  mov    %rbp,%rdi
  mov    %rax,%r12
  call   <cg_name@plt>
  mov    %rax,%r13
  test   %r12,%r12
  je     L6
  test   %rax,%rax
  je     L6
  mov    %r12,%rdi
  call   <cg_create@plt>
  test   %rax,%rax
  je     L118
L81:
  mov    $0x1,%r14d
L129:
  mov    %rbp,%rdi
  call   <cg_enter_current@plt>
  mov    %rbp,%rdi
  call   <cg_enter_current@plt>
L134:
  mov    %r13,%rdi
  call   <cg_destroy@plt>
L126:
  test   %r12,%r12
  je     L120
  mov    %r12,%rdi
  call   <cg_destroy@plt>
  jmp    L120
  cs nopw 0x0(%rax,%rax,1)
L8:
  mov    %rbp,%rdi
  xor    %r13d,%r13d
  xor    %r12d,%r12d
  mov    $0x4,%r14d
  call   <cg_enter_current@plt>
  mov    %rbp,%rdi
  call   <cg_enter_current@plt>
L120:
  mov    %r13,%rdi
  call   <free@plt>
  mov    %r12,%rdi
  call   <free@plt>
  add    $0x8,%rsp
  mov    %r14d,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  xchg   %ax,%ax
L6:
  mov    %rbp,%rdi
  mov    $0x1,%r14d
  call   <cg_enter_current@plt>
  mov    %rbp,%rdi
  call   <cg_enter_current@plt>
  test   %r13,%r13
  jne    L134
  jmp    L126
  nopl   (%rax)
L118:
  mov    %r13,%rdi
  call   <cg_create@plt>
  test   %rax,%rax
  jne    L81
  lea    D65(%rip),%rbx
  lea    D45(%rip),%rdx
  mov    %r12,%rdi
  mov    %rbx,%rsi
  call   <cg_write@plt>
  test   %rax,%rax
  jne    L81
  lea    D45(%rip),%rdx
  mov    %rbx,%rsi
  mov    %r13,%rdi
  call   <cg_write@plt>
  test   %rax,%rax
  jne    L81
  mov    %r15,%rdx
  mov    %r14,%rsi
  mov    %r12,%rdi
  call   <cg_write@plt>
  test   %rax,%rax
  jne    L81
  mov    %r12,%rdi
  xor    %r14d,%r14d
  call   <cg_enter_current@plt>
  test   %rax,%rax
  setne  %r14b
  jmp    L129
```

tool_calls: name: read_data
arguments: data_label: D38
type_guessed: string
name: read_data
arguments: data_label: D86
type_guessed: string
name: read_data
arguments: data_label: D23
type_guessed: string
name: read_data
arguments: data_label: D84
type_guessed: string
name: read_data
arguments: data_label: D81
type_guessed: string
name: read_data
arguments: data_label: D18
type_guessed: string
name: read_data
arguments: data_label: D65
type_guessed: string
name: read_data
arguments: data_label: D45
type_guessed: string

tool: D38: cpu

tool: D86: cgroup.controllers

tool: D23: +cpu

tool: D84: cgroup.subtree_control

tool: D81: cg_test_parent

tool: D18: cg_test_parent/cg_test_child

tool: D65: cgroup.type

tool: D45: threaded

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;
}
```