// File: /workspace/github_c_makefile_star2_O3/wahern[P]cqueues/src/thread.c
// Function: ct_enter
static void *ct_enter(void *arg) {
	struct cthread *ct = arg, **ud;
	lua_State *L = NULL;
	int error;

	/*
	 * Hold down deadman switch so ct_join can detect (on some systems)
	 * whether thread was killed or cancelled.
	 */
	hdl_hold(&ct->handle);

	/*
	 * Procedure for bootstrapping into a new Lua VM. Order is important
	 * because arg[0..N] are interned strings from the parent Lua VM.
	 *
	 *  1) Acquire lock.
	 *  -- BEGIN CRITICAL SECTION --
	 *  2) Grab struct cthread reference.
	 *  3) Open new main Lua thread.
	 *  4) Set Lua panic trap.
	 *  5) Load low-level components from memory as we might be
	 *     chroot'd and unable to load them from disk.
	 *  6) Load arg[0] as our Lua start routine.
	 *  7) Push reference to struct cthread.
	 *  8) Push reference to our socket.
	 *  9) Push strings arg[1..N].
	 *  -- END CRITICAL SECTION --
	 * 10) Release lock and signal parent.
	 * 11) Reset Lua panic trap.
	 * 12) Call Lua start routine.
	 *
	 * NOTE: Lua user code perceives this process differently. See
	 * thread.lua.
	 */
	pthread_mutex_lock(&ct->mutex);

	ct->refs++;

	if (!(L = luaL_newstate()))
		goto syerr;

	if ((error = pthread_once(&atpanic.once, &atpanic_once)))
		goto error;

	if ((error = pthread_setspecific(atpanic.key, ct)))
		goto error;

	lua_atpanic(L, &atpanic_trap);

	if ((error = _setjmp(ct->trap)))
		goto error;

	luaL_openlibs(L);
	cqs_openlibs(L);

	if (ct->tmp.arg[0].iscfunction) {
		lua_pushcfunction(L, EXTENSION (lua_CFunction)ct->tmp.arg[0].v.pointer);
	} else {
		luaL_loadbuffer(L, ct->tmp.arg[0].v.string.iov_base, ct->tmp.arg[0].v.string.iov_len, "[thread enter]");
	}

	ud = lua_newuserdata(L, sizeof *ud);
	*ud = NULL;

	luaL_getmetatable(L, CQS_THREAD);
	lua_setmetatable(L, -2);

	ct->refs++;
	*ud = ct;

	lua_pushvalue(L, -1);
	lua_rawsetp(L, LUA_REGISTRYINDEX, CQS_UNIQUE_LIGHTUSERDATA_MASK(&selfindex));

	if ((error = cqs_socket_fdopen(L, ct->tmp.fd[1], NULL)))
		goto error;

	ct->tmp.fd[1] = -1;

	for (struct cthread_arg *arg = &ct->tmp.arg[1]; arg < &ct->tmp.arg[ct->tmp.argc]; arg++) {
		switch (arg->type) {
		case LUA_TNUMBER:
			if (arg->isinteger) {
				lua_pushinteger(L, arg->v.integer);
			} else {
				lua_pushnumber(L, arg->v.number);
			}
			break;
		case LUA_TBOOLEAN:
			lua_pushboolean(L, arg->v.boolean);
			break;
		case LUA_TLIGHTUSERDATA:
			lua_pushlightuserdata(L, arg->v.pointer);
			break;
		case LUA_TSTRING:
			lua_pushlstring(L, arg->v.string.iov_base, arg->v.string.iov_len);
			break;
		case LUA_TFUNCTION:
			if (arg->iscfunction) {
				lua_pushcfunction(L, EXTENSION (lua_CFunction)arg->v.pointer);
			} else {
				luaL_loadbuffer(L, arg->v.string.iov_base, arg->v.string.iov_len, NULL);
			}
			break;
		default:
			lua_pushnil(L);
			break;
		}
	}

	free(ct->tmp.arg);
	ct->tmp.arg = NULL;
	ct->tmp.argc = 0;

	pthread_mutex_unlock(&ct->mutex);
	pthread_cond_signal(&ct->cond);

	if ((error = _setjmp(ct->trap))) {
		ct->error = error;
		goto close;
	}

	ct->status = lua_pcall(L, lua_gettop(L) - 1, 0, 0);

	if (ct->status != LUA_OK && lua_isstring(L, -1)) {
		if (!(ct->msg = strdup(lua_tostring(L, -1)))) {
			ct->error = errno;
		}
	}
close:
	if (L) {
		if (!(error = _setjmp(ct->trap))) {
			lua_close(L);
		} else if (!ct->error) {
			ct->error = error;
		}
	}

	cqs_closefd(&ct->pipe[1]);

	ct_release(ct);

	return 0;
syerr:
	error = errno;
error: /* NOTE: Only critical section errors reach here. */
	ct->error = error;

	pthread_mutex_unlock(&ct->mutex);
	pthread_cond_signal(&ct->cond);

	goto close;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
addq $0x180, %rdi            # imm = 0x180
callq 0x103b0
testl %eax, %eax
jne 0x1dd1c
movl $0x1, 0x178(%rbx)
leaq 0x20(%rbx), %r12
movq %r12, %rdi
callq 0x103b0
incl (%rbx)
callq 0x103a0
movq %rax, %r15
movq %rax, %r14
testq %rax, %rax
je 0x1de6c
leaq 0x2a8a3(%rip), %rdi     # 0x485e8
leaq 0x3cb(%rip), %rsi       # 0x1e117
callq 0xfc40
testl %eax, %eax
jne 0x1de73
movl 0x2a88d(%rip), %edi     # 0x485ec
movq %rbx, %rsi
callq 0xf270
testl %eax, %eax
jne 0x1de73
leaq 0x3b8(%rip), %rsi       # 0x1e12e
movq %r14, %rdi
callq 0x10990
leaq 0xb0(%rbx), %r13
movq %r13, %rdi
callq 0x10320
testl %eax, %eax
jne 0x1de73
movq %r14, %rdi
callq 0xf8c0
movq %r14, %rdi
callq 0xf920
movl %eax, %ebp
leaq 0x1827d(%rip), %rsi     # 0x3602b
movq 0x291bb(%rip), %rdx     # 0x46f70
movq %r14, %rdi
callq 0x1e156
leaq 0x18270(%rip), %rsi     # 0x36034
movq 0x2920d(%rip), %rdx     # 0x46fd8
movq %r14, %rdi
callq 0x1e156
leaq 0x1728f(%rip), %rsi     # 0x35069
movq 0x291bf(%rip), %rdx     # 0x46fa0
movq %r14, %rdi
callq 0x1e156
leaq 0x18253(%rip), %rsi     # 0x36043
movq 0x291a1(%rip), %rdx     # 0x46f98
movq %r14, %rdi
callq 0x1e156
leaq 0x1824d(%rip), %rsi     # 0x36053
movq 0x291d3(%rip), %rdx     # 0x46fe0
movq %r14, %rdi
callq 0x1e156
leaq 0x18247(%rip), %rsi     # 0x36063
movq 0x291c5(%rip), %rdx     # 0x46fe8
movq %r14, %rdi
callq 0x1e156
movq %r14, %rdi
movl %ebp, %esi
callq 0x10640
movq 0x1b8(%rbx), %rax
testb $0x1, 0x4(%rax)
movq 0x8(%rax), %rsi
movq %r13, 0x10(%rsp)
jne 0x1dee2
movq 0x10(%rax), %rdx
leaq 0x181c2(%rip), %rcx     # 0x3601c
xorl %eax, %eax
movl %eax, %r8d
movq %r14, %rdi
callq 0xfc70
jmp 0x1deec
callq 0xf0a0
movl (%rax), %eax
movl %eax, 0x4(%rbx)
movq %r12, %rdi
callq 0xf9b0
leaq 0x48(%rbx), %rdi
callq 0xf040
testq %r15, %r15
je 0x1deaf
leaq 0xb0(%rbx), %rdi
callq 0x10320
testl %eax, %eax
je 0x1dea7
cmpl $0x0, 0x4(%rbx)
jne 0x1deaf
movl %eax, 0x4(%rbx)
jmp 0x1deaf
movq %r14, %rdi
callq 0xf9d0
movl 0x1ac(%rbx), %edi
cmpl $-0x1, %edi
je 0x1dec9
callq 0x10a10
movl $0xffffffff, 0x1ac(%rbx) # imm = 0xFFFFFFFF
movq %rbx, %rdi
callq 0x1ccc9
xorl %eax, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r14, %rdi
xorl %edx, %edx
callq 0x109f0
movl $0x8, %esi
movq %r14, %rdi
callq 0xfb00
movq %rax, %rbp
movq $0x0, (%rax)
leaq 0x180a2(%rip), %rdx     # 0x35fac
movl $0xfff0b9d8, %r13d      # imm = 0xFFF0B9D8
movq %r14, %rdi
movl %r13d, %esi
callq 0xf1e0
movq %r14, %rdi
movl $0xfffffffe, %esi       # imm = 0xFFFFFFFE
callq 0x10910
incl (%rbx)
movq %rbx, (%rbp)
movq %r14, %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0xf9c0
leaq 0x18066(%rip), %rdx     # 0x35fa8
movq %r14, %rdi
movl %r13d, %esi
callq 0xf160
movl 0x1c8(%rbx), %esi
xorl %eax, %eax
movl %eax, %edx
movq %r14, %rdi
callq 0x10170
testl %eax, %eax
jne 0x1de73
movl $0xffffffff, 0x1c8(%rbx) # imm = 0xFFFFFFFF
movq 0x1b8(%rbx), %rbp
cmpl $0x2, 0x1c0(%rbx)
jb 0x1e05a
addq $0x18, %rbp
leaq 0x18000(%rip), %r13     # 0x35f90
xorl %eax, %eax
movq %rax, 0x8(%rsp)
movl (%rbp), %eax
decl %eax
cmpl $0x5, %eax
ja 0x1dfb9
movslq (%r13,%rax,4), %rax
addq %r13, %rax
jmpq *%rax
movzbl 0x8(%rbp), %esi
movq %r14, %rdi
callq 0x10800
jmp 0x1e030
movq %r14, %rdi
callq 0xf980
jmp 0x1e030
testb $0x2, 0x4(%rbp)
jne 0x1e018
movsd 0x8(%rbp), %xmm0
movq %r14, %rdi
callq 0xf2c0
jmp 0x1e030
movq 0x8(%rbp), %rsi
movq %r14, %rdi
callq 0x10150
jmp 0x1e030
movq 0x8(%rbp), %rsi
movq 0x10(%rbp), %rdx
movq %r14, %rdi
callq 0xf4c0
jmp 0x1e030
testb $0x1, 0x4(%rbp)
movq 0x8(%rbp), %rsi
jne 0x1e026
movq 0x10(%rbp), %rdx
movq %r14, %rdi
movq 0x8(%rsp), %rcx
movq %rcx, %r8
callq 0xfc70
jmp 0x1e030
movq 0x8(%rbp), %rsi
movq %r14, %rdi
callq 0xf910
jmp 0x1e030
movq %r14, %rdi
xorl %edx, %edx
callq 0x109f0
movq %rbp, %rax
addq $0x18, %rax
movq 0x1b8(%rbx), %rdi
movl 0x1c0(%rbx), %ecx
leaq (%rcx,%rcx,2), %rcx
leaq (%rdi,%rcx,8), %rcx
movq %rax, %rbp
cmpq %rcx, %rax
jb 0x1df97
jmp 0x1e05d
movq %rbp, %rdi
callq 0xff30
movq $0x0, 0x1b8(%rbx)
movl $0x0, 0x1c0(%rbx)
movq %r12, %rdi
callq 0xf9b0
leaq 0x48(%rbx), %rdi
callq 0xf040
movq 0x10(%rsp), %rdi
callq 0x10320
testl %eax, %eax
je 0x1e09e
movl %eax, 0x4(%rbx)
jmp 0x1de87
movq %r14, %rdi
callq 0xf920
leal -0x1(%rax), %esi
xorl %ecx, %ecx
movl %ecx, %r8d
movq %r14, %rdi
movl %ecx, %edx
movq %r8, %r9
callq 0xf990
movl %eax, 0x8(%rbx)
testl %eax, %eax
je 0x1de87
movq %r14, %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x106f0
testl %eax, %eax
je 0x1de87
xorl %eax, %eax
movl %eax, %edx
movq %r14, %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0xf110
movq %rax, %rdi
callq 0x10890
movq %rax, 0x10(%rbx)
testq %rax, %rax
jne 0x1de87
callq 0xf0a0
movl (%rax), %eax
jmp 0x1e096