PageRenderTime 34ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/src/runtime/x86-win32-os.c

http://github.com/akovalenko/sbcl-win32-threads
C | 211 lines | 141 code | 35 blank | 35 comment | 3 complexity | f4970da86074b2f95d064ddc0d6db478 MD5 | raw file
  1. /*
  2. * The x86 Win32 incarnation of arch-dependent OS-dependent routines.
  3. * See also "win32-os.c".
  4. */
  5. /*
  6. * This software is part of the SBCL system. See the README file for
  7. * more information.
  8. *
  9. * This software is derived from the CMU CL system, which was
  10. * written at Carnegie Mellon University and released into the
  11. * public domain. The software is in the public domain and is
  12. * provided with absolutely no warranty. See the COPYING and CREDITS
  13. * files for more information.
  14. */
  15. #include <stdio.h>
  16. #include <stddef.h>
  17. #include <sys/param.h>
  18. #include <sys/file.h>
  19. #include <sys/types.h>
  20. #include <unistd.h>
  21. #include <errno.h>
  22. #include "os.h"
  23. #include "arch.h"
  24. #include "globals.h"
  25. #include "interrupt.h"
  26. #include "interr.h"
  27. #include "lispregs.h"
  28. #include "sbcl.h"
  29. #include <sys/types.h>
  30. #include "runtime.h"
  31. #include <sys/time.h>
  32. #include <sys/stat.h>
  33. #include <unistd.h>
  34. #include "thread.h" /* dynamic_values_bytes */
  35. #include "cpputil.h" /* PTR_ALIGN... */
  36. #include "validate.h"
  37. static boolean have_sse2()
  38. {
  39. int request = 1;
  40. int edx;
  41. asm ("cpuid;"
  42. :"=d"(edx)
  43. :"a"(request)
  44. :"%ebx","%ecx");
  45. return (edx & 0x04000000)!=0;
  46. }
  47. void (*fast_fill_pointer)(void*addr, size_t len, lispobj pattern);
  48. static void fast_fill_sse2(void*addr, size_t len, lispobj pattern)
  49. {
  50. extern void fast_wordfill_sse(void*addr, size_t len,
  51. int w1, int w2, int w3, int w4);
  52. fast_wordfill_sse(addr,len,pattern,pattern,pattern,pattern);
  53. }
  54. static void fast_fill_base(void*addr, size_t len, lispobj pattern)
  55. {
  56. lispobj* ptr = addr;
  57. while(len--)
  58. *(ptr++) = pattern;
  59. }
  60. static void fast_fill_detect(void*addr, size_t len, lispobj pattern)
  61. {
  62. if (have_sse2())
  63. fast_fill_pointer = fast_fill_sse2;
  64. else
  65. fast_fill_pointer = fast_fill_base;
  66. fast_fill_pointer(addr,len,pattern);
  67. }
  68. void (*fast_fill_pointer)(void*addr, size_t len, lispobj pattern)
  69. = fast_fill_detect;
  70. int arch_os_thread_init(struct thread *thread)
  71. {
  72. {
  73. void *top_exception_frame;
  74. void *cur_stack_end;
  75. void *cur_stack_start;
  76. MEMORY_BASIC_INFORMATION stack_memory;
  77. asm volatile ("movl %%fs:0,%0": "=r" (top_exception_frame));
  78. asm volatile ("movl %%fs:4,%0": "=r" (cur_stack_end));
  79. /* Can't pull stack start from fs:4 or fs:8 or whatever,
  80. * because that's only what currently has memory behind
  81. * it from being used, so do a quick VirtualQuery() and
  82. * grab the AllocationBase. -AB 2006/11/25
  83. */
  84. if (!VirtualQuery(&stack_memory, &stack_memory, sizeof(stack_memory))) {
  85. fprintf(stderr, "VirtualQuery: 0x%lx.\n", GetLastError());
  86. lose("Could not query stack memory information.");
  87. }
  88. cur_stack_start = stack_memory.AllocationBase
  89. /* OS provides its own guard page at the stack start,
  90. and we have ours. Do you really want to see how they interact? */
  91. + os_vm_page_size;
  92. /* We use top_exception_frame rather than cur_stack_end to
  93. * elide the last few (boring) stack entries at the bottom of
  94. * the backtrace.
  95. */
  96. thread->control_stack_start = cur_stack_start;
  97. thread->control_stack_end = top_exception_frame;
  98. thread->csp_around_foreign_call =
  99. PTR_ALIGN_UP((void*)(((lispobj*)thread) + TLS_SIZE), os_vm_page_size) +
  100. ((void*)thread - PTR_ALIGN_DOWN((void*)thread,os_vm_page_size));
  101. #ifndef LISP_FEATURE_SB_THREAD
  102. /*
  103. * Theoretically, threaded SBCL binds directly against
  104. * the thread structure for these values. We don't do
  105. * threads yet, but we'll probably do the same. We do
  106. * need to reset these, though, because they were
  107. * initialized based on the wrong stack space.
  108. */
  109. SetSymbolValue(CONTROL_STACK_START,(lispobj)thread->control_stack_start,thread);
  110. SetSymbolValue(CONTROL_STACK_END,(lispobj)thread->control_stack_end,thread);
  111. #endif
  112. }
  113. #ifdef LISP_FEATURE_SB_THREAD
  114. TlsSetValue(OUR_TLS_INDEX,thread);
  115. #endif
  116. return 1;
  117. }
  118. /* free any arch/os-specific resources used by thread, which is now
  119. * defunct. Not called on live threads
  120. */
  121. int arch_os_thread_cleanup(struct thread *thread) {
  122. return 0;
  123. }
  124. #if defined(LISP_FEATURE_SB_THREAD)
  125. sigset_t *os_context_sigmask_addr(os_context_t *context)
  126. {
  127. return &context->sigmask;
  128. }
  129. #endif
  130. os_context_register_t *
  131. os_context_register_addr(os_context_t *context, int offset)
  132. {
  133. static const size_t offsets[8] = {
  134. offsetof(CONTEXT,Eax),
  135. offsetof(CONTEXT,Ecx),
  136. offsetof(CONTEXT,Edx),
  137. offsetof(CONTEXT,Ebx),
  138. offsetof(CONTEXT,Esp),
  139. offsetof(CONTEXT,Ebp),
  140. offsetof(CONTEXT,Esi),
  141. offsetof(CONTEXT,Edi),
  142. };
  143. return
  144. (offset >= 0 && offset < 16) ?
  145. ((void*)(context->win32_context)) + offsets[offset>>1] : 0;
  146. }
  147. os_context_register_t *
  148. os_context_pc_addr(os_context_t *context)
  149. {
  150. return (void*)&context->win32_context->Eip; /* REG_EIP */
  151. }
  152. os_context_register_t *
  153. os_context_sp_addr(os_context_t *context)
  154. {
  155. return (void*)&context->win32_context->Esp; /* REG_UESP */
  156. }
  157. os_context_register_t *
  158. os_context_fp_addr(os_context_t *context)
  159. {
  160. return (void*)&context->win32_context->Ebp; /* REG_EBP */
  161. }
  162. unsigned long
  163. os_context_fp_control(os_context_t *context)
  164. {
  165. return ((((context->win32_context->FloatSave.ControlWord) & 0xffff) ^ 0x3f) |
  166. (((context->win32_context->FloatSave.StatusWord) & 0xffff) << 16));
  167. }
  168. void
  169. os_restore_fp_control(os_context_t *context)
  170. {
  171. asm ("fldcw %0" : : "m" (context->win32_context->FloatSave.ControlWord));
  172. }
  173. void
  174. os_flush_icache(os_vm_address_t address, os_vm_size_t length)
  175. {
  176. }