mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
simple_threads for win32
This commit is contained in:
parent
bebefc5563
commit
9ad516cea2
@ -89,18 +89,62 @@ switch_to_thread_context(struct ThreadContext *context) {
|
||||
_jmp_context. Then restore back to the original stack pointer. */
|
||||
|
||||
#if defined(_M_IX86)
|
||||
/* Here is own own implementation of setjmp and longjmp for I386, via
|
||||
/* Here is our own implementation of setjmp and longjmp for I386, via
|
||||
Windows syntax. */
|
||||
|
||||
int cs_setjmp(cs_jmp_buf env);
|
||||
void cs_longjmp(cs_jmp_buf env);
|
||||
/* warning C4731: frame pointer register 'ebp' modified by inline assembly code */
|
||||
#pragma warning(disable:4731)
|
||||
|
||||
int
|
||||
cs_setjmp(cs_jmp_buf env) {
|
||||
__asm {
|
||||
pop ebp; /* Restore the frame pointer that the compiler pushed */
|
||||
|
||||
pop edx; /* edx = return address */
|
||||
pop eax; /* eax = &env */
|
||||
push eax; /* keep &env on the stack; the caller will remove it */
|
||||
|
||||
mov [eax + 0], ebx;
|
||||
mov [eax + 4], edi;
|
||||
mov [eax + 8], esi;
|
||||
mov [eax + 12], ebp;
|
||||
mov [eax + 16], esp;
|
||||
mov [eax + 20], edx;
|
||||
|
||||
fnsave [eax + 24]; /* save floating-point state */
|
||||
|
||||
xor eax,eax; /* return 0: pass 1 return */
|
||||
jmp edx; /* this works like ret */
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cs_longjmp(cs_jmp_buf env) {
|
||||
_asm {
|
||||
mov eax, env;
|
||||
|
||||
mov ebx, [eax + 0];
|
||||
mov edi, [eax + 4];
|
||||
mov esi, [eax + 8];
|
||||
mov ebp, [eax + 12];
|
||||
mov esp, [eax + 16];
|
||||
mov edx, [eax + 20];
|
||||
|
||||
frstor [eax + 24]; /* restore floating-point state */
|
||||
|
||||
mov eax, 1; /* return 1 from setjmp: pass 2 return */
|
||||
jmp edx; /* return from above setjmp call */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined(__i386__)
|
||||
/* Here is own own implementation of setjmp and longjmp for I386, via
|
||||
/* Here is our own implementation of setjmp and longjmp for I386, via
|
||||
GNU syntax. */
|
||||
|
||||
#if defined(IS_LINUX)
|
||||
/* On Linux, the underscores are not implicit. */
|
||||
/* On Linux, the leading underscores are not implicitly added for C
|
||||
function names. */
|
||||
#define cs_setjmp _cs_setjmp
|
||||
#define cs_longjmp _cs_longjmp
|
||||
#endif
|
||||
@ -113,13 +157,16 @@ __asm__
|
||||
"popl %edx\n"
|
||||
"popl %eax\n"
|
||||
"pushl %eax\n"
|
||||
|
||||
"movl %ebx, 0(%eax)\n"
|
||||
"movl %edi, 4(%eax)\n"
|
||||
"movl %esi, 8(%eax)\n"
|
||||
"movl %ebp, 12(%eax)\n"
|
||||
"movl %esp, 16(%eax)\n"
|
||||
"movl %edx, 20(%eax)\n"
|
||||
|
||||
"fnsave 24(%eax)\n"
|
||||
|
||||
"xorl %eax, %eax\n"
|
||||
"jmp *%edx\n");
|
||||
|
||||
@ -127,13 +174,16 @@ __asm__
|
||||
("_cs_longjmp:\n"
|
||||
"popl %edx\n"
|
||||
"popl %eax\n"
|
||||
|
||||
"movl 0(%eax), %ebx\n"
|
||||
"movl 4(%eax), %edi\n"
|
||||
"movl 8(%eax), %esi\n"
|
||||
"movl 12(%eax), %ebp\n"
|
||||
"movl 16(%eax), %esp\n"
|
||||
"movl 20(%eax), %edx\n"
|
||||
|
||||
"frstor 24(%eax)\n"
|
||||
|
||||
"mov $1,%eax\n"
|
||||
"jmp *%edx\n");
|
||||
|
||||
@ -149,11 +199,6 @@ __asm__
|
||||
this directory. */
|
||||
#define CS_JB_SP 9
|
||||
|
||||
#elif defined(WIN32)
|
||||
/* We have determined this value empirically, via test_setjmp.cxx in
|
||||
this directory. */
|
||||
#define CS_JB_SP 4
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* CS_JB_SP */
|
||||
|
@ -49,7 +49,7 @@ struct ThreadContext {
|
||||
it claims to be adopted by Posix). So we have to fall back to
|
||||
setjmp() / longjmp() in its absence. This is a hackier solution. */
|
||||
|
||||
#if defined(__i386__)
|
||||
#if defined(_M_IX86) || defined(__i386__)
|
||||
/* Maybe we can implement our own setjmp/longjmp in assembly code.
|
||||
This will be safe than the system version, since who knows what
|
||||
that one's really doing? */
|
||||
|
@ -24,6 +24,11 @@
|
||||
#include "threadSimpleManager.h"
|
||||
#include "thread.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
ThreadSimpleImpl *volatile ThreadSimpleImpl::_st_this;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -45,7 +50,14 @@ ThreadSimpleImpl(Thread *parent_obj) :
|
||||
// We allocate the requested stack size, plus an additional tiny
|
||||
// buffer to allow room for the code to access values on the
|
||||
// currently executing stack frame at the time we switch the stack.
|
||||
_stack = (unsigned char *)malloc(_stack_size + 0x100);
|
||||
size_t alloc_size = _stack_size + 0x100;
|
||||
|
||||
#ifdef WIN32
|
||||
_stack = (unsigned char *)VirtualAlloc(NULL, alloc_size, MEM_COMMIT | MEM_RESERVE,
|
||||
PAGE_EXECUTE_READWRITE);
|
||||
#else
|
||||
_stack = (unsigned char *)malloc(alloc_size);
|
||||
#endif
|
||||
|
||||
// Save this pointer for convenience.
|
||||
_manager = ThreadSimpleManager::get_global_ptr();
|
||||
@ -64,7 +76,13 @@ ThreadSimpleImpl::
|
||||
}
|
||||
nassertv(_status != S_running);
|
||||
|
||||
if (_stack != (void *)NULL) {
|
||||
#ifdef WIN32
|
||||
VirtualFree(_stack, 0, MEM_RELEASE);
|
||||
#else
|
||||
free(_stack);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
x
Reference in New Issue
Block a user