mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -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. */
|
_jmp_context. Then restore back to the original stack pointer. */
|
||||||
|
|
||||||
#if defined(_M_IX86)
|
#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. */
|
Windows syntax. */
|
||||||
|
|
||||||
int cs_setjmp(cs_jmp_buf env);
|
/* warning C4731: frame pointer register 'ebp' modified by inline assembly code */
|
||||||
void cs_longjmp(cs_jmp_buf env);
|
#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__)
|
#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. */
|
GNU syntax. */
|
||||||
|
|
||||||
#if defined(IS_LINUX)
|
#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_setjmp _cs_setjmp
|
||||||
#define cs_longjmp _cs_longjmp
|
#define cs_longjmp _cs_longjmp
|
||||||
#endif
|
#endif
|
||||||
@ -113,27 +157,33 @@ __asm__
|
|||||||
"popl %edx\n"
|
"popl %edx\n"
|
||||||
"popl %eax\n"
|
"popl %eax\n"
|
||||||
"pushl %eax\n"
|
"pushl %eax\n"
|
||||||
"movl %ebx,0(%eax)\n"
|
|
||||||
"movl %edi,4(%eax)\n"
|
"movl %ebx, 0(%eax)\n"
|
||||||
"movl %esi,8(%eax)\n"
|
"movl %edi, 4(%eax)\n"
|
||||||
"movl %ebp,12(%eax)\n"
|
"movl %esi, 8(%eax)\n"
|
||||||
"movl %esp,16(%eax)\n"
|
"movl %ebp, 12(%eax)\n"
|
||||||
"movl %edx,20(%eax)\n"
|
"movl %esp, 16(%eax)\n"
|
||||||
|
"movl %edx, 20(%eax)\n"
|
||||||
|
|
||||||
"fnsave 24(%eax)\n"
|
"fnsave 24(%eax)\n"
|
||||||
"xorl %eax,%eax\n"
|
|
||||||
|
"xorl %eax, %eax\n"
|
||||||
"jmp *%edx\n");
|
"jmp *%edx\n");
|
||||||
|
|
||||||
__asm__
|
__asm__
|
||||||
("_cs_longjmp:\n"
|
("_cs_longjmp:\n"
|
||||||
"popl %edx\n"
|
"popl %edx\n"
|
||||||
"popl %eax\n"
|
"popl %eax\n"
|
||||||
"movl 0(%eax),%ebx\n"
|
|
||||||
"movl 4(%eax),%edi\n"
|
"movl 0(%eax), %ebx\n"
|
||||||
"movl 8(%eax),%esi\n"
|
"movl 4(%eax), %edi\n"
|
||||||
"movl 12(%eax),%ebp\n"
|
"movl 8(%eax), %esi\n"
|
||||||
"movl 16(%eax),%esp\n"
|
"movl 12(%eax), %ebp\n"
|
||||||
"movl 20(%eax),%edx\n"
|
"movl 16(%eax), %esp\n"
|
||||||
|
"movl 20(%eax), %edx\n"
|
||||||
|
|
||||||
"frstor 24(%eax)\n"
|
"frstor 24(%eax)\n"
|
||||||
|
|
||||||
"mov $1,%eax\n"
|
"mov $1,%eax\n"
|
||||||
"jmp *%edx\n");
|
"jmp *%edx\n");
|
||||||
|
|
||||||
@ -149,11 +199,6 @@ __asm__
|
|||||||
this directory. */
|
this directory. */
|
||||||
#define CS_JB_SP 9
|
#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
|
||||||
|
|
||||||
#endif /* CS_JB_SP */
|
#endif /* CS_JB_SP */
|
||||||
|
@ -49,7 +49,7 @@ struct ThreadContext {
|
|||||||
it claims to be adopted by Posix). So we have to fall back to
|
it claims to be adopted by Posix). So we have to fall back to
|
||||||
setjmp() / longjmp() in its absence. This is a hackier solution. */
|
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.
|
/* Maybe we can implement our own setjmp/longjmp in assembly code.
|
||||||
This will be safe than the system version, since who knows what
|
This will be safe than the system version, since who knows what
|
||||||
that one's really doing? */
|
that one's really doing? */
|
||||||
|
@ -24,6 +24,11 @@
|
|||||||
#include "threadSimpleManager.h"
|
#include "threadSimpleManager.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
ThreadSimpleImpl *volatile ThreadSimpleImpl::_st_this;
|
ThreadSimpleImpl *volatile ThreadSimpleImpl::_st_this;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -45,7 +50,14 @@ ThreadSimpleImpl(Thread *parent_obj) :
|
|||||||
// We allocate the requested stack size, plus an additional tiny
|
// We allocate the requested stack size, plus an additional tiny
|
||||||
// buffer to allow room for the code to access values on the
|
// buffer to allow room for the code to access values on the
|
||||||
// currently executing stack frame at the time we switch the stack.
|
// 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.
|
// Save this pointer for convenience.
|
||||||
_manager = ThreadSimpleManager::get_global_ptr();
|
_manager = ThreadSimpleManager::get_global_ptr();
|
||||||
@ -64,7 +76,13 @@ ThreadSimpleImpl::
|
|||||||
}
|
}
|
||||||
nassertv(_status != S_running);
|
nassertv(_status != S_running);
|
||||||
|
|
||||||
free(_stack);
|
if (_stack != (void *)NULL) {
|
||||||
|
#ifdef WIN32
|
||||||
|
VirtualFree(_stack, 0, MEM_RELEASE);
|
||||||
|
#else
|
||||||
|
free(_stack);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
Loading…
x
Reference in New Issue
Block a user