Changeset 13431


Ignore:
Timestamp:
Feb 4, 2010, 12:48:07 PM (9 years ago)
Author:
gb
Message:

Try to address ticket:649 by clearly distinguishing between UnMapMemory?()
(which completely deallocates an entire memory region created by MapMemory?()
or MapMemoryForStack?()) from UnCommitMemory?() (which leaves a previously
mapped and accessible range of pages mapped but inaccessible/uncommitted.)

Follow Alexander Gavrilov's suggestions (and use his patch) to ensure
that thread handles are closed on Windows. Make create_system_thread()
return a Boolean, since no callers care about the exact value and the
value that was returned on Windows was a handle that needed to be closed.

Ensure that create_system_thread() observes its stack_size argument.
Make the size of vstack soft protected area ("the yellow zone") larger.

Use a readable/writable PAGE_GUARD page at the bottom of the
cstack/tstack yellow zone and handle the Windows exception that's
raised when a PAGE_GUARD page is written to, so that stack overflow
detection has a prayer of working on Windows.

UNTESTED ANYWHERE BUT WIN32.

Location:
trunk/source/lisp-kernel
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/lisp-kernel/Threads.h

    r13067 r13431  
    183183
    184184
    185 LispObj create_system_thread(size_t stack_size,
     185Boolean create_system_thread(size_t stack_size,
    186186                             void* stackaddr,
    187187#ifdef WINDOWS
  • trunk/source/lisp-kernel/area.h

    r13279 r13431  
    124124#define MIN_VSTACK_SIZE (1<<16)
    125125#define VSTACK_HARDPROT (1<<12)
     126#ifdef PPC
    126127#define VSTACK_SOFTPROT (1<<16)
     128#else
     129#define VSTACK_SOFTPROT CSTACK_SOFTPROT
     130#endif
    127131#define MIN_TSTACK_SIZE (1<<18)
    128132#define TSTACK_HARDPROT 0
  • trunk/source/lisp-kernel/memory.c

    r13279 r13431  
    313313}
    314314
     315
     316/* Cause the mapped memory region at ADDR to become completely unmapped.
     317   ADDR should be an address returned by MapMemoryForStack() or MapMemory(),
     318   and NBYTES should be the size of the mapped region at that address. */
    315319int
    316320UnMapMemory(LogicalAddress addr, natural nbytes)
     
    320324#endif
    321325#ifdef WINDOWS
    322   /* Can't MEM_RELEASE here because we only want to free a chunk */
    323   return VirtualFree(addr, nbytes, MEM_DECOMMIT);
     326  return !VirtualFree(addr, 0, MEM_RELEASE);
    324327#else
    325328  return munmap(addr, nbytes);
     
    457460}
    458461
    459 /*
    460   Un-protect the first nbytes bytes in specified area.
    461   Note that this may cause the area to be empty.
    462 */
    463 void
    464 unprotect_area_prefix(protected_area_ptr area, size_t delta)
    465 {
    466   unprotect_area(area);
    467   area->start += delta;
    468   if ((area->start + area->protsize) <= area->end) {
    469     protect_area(area);
    470   }
    471 }
    472 
    473 
    474 /*
    475   Extend the protected area, causing the preceding nbytes bytes
    476   to be included and protected.
    477 */
    478 void
    479 protect_area_prefix(protected_area_ptr area, size_t delta)
    480 {
    481   unprotect_area(area);
    482   area->start -= delta;
    483   protect_area(area);
    484 }
     462
     463
    485464
    486465protected_area_ptr
     
    556535  if (n && ! p->nprot) {
    557536    ProtectMemory(start, n);
     537#ifdef WINDOWS
     538    VirtualAlloc(start+n-page_size,page_size,MEM_COMMIT,PAGE_READWRITE|PAGE_GUARD);
     539#endif
    558540    p->nprot = n;
    559541  }
  • trunk/source/lisp-kernel/thread_manager.c

    r13279 r13431  
    14251425    free(tcr->tlb_pointer);
    14261426    tcr->tlb_pointer = NULL;
     1427#ifdef WINDOWS
     1428    if (tcr->osid != 0) {
     1429      CloseHandle((HANDLE)(tcr->osid));
     1430    }
     1431#endif
    14271432    tcr->osid = 0;
    14281433    tcr->interrupt_pending = 0;
     
    18191824
    18201825#ifdef WINDOWS
    1821 LispObj
     1826Boolean
    18221827create_system_thread(size_t stack_size,
    18231828                     void* stackaddr,
     
    18261831{
    18271832  HANDLE thread_handle;
     1833  Boolean won = false;
    18281834
    18291835  stack_size = ((stack_size+(((1<<16)-1)))&~((1<<16)-1));
    18301836
    18311837  thread_handle = (HANDLE)_beginthreadex(NULL,
    1832                                          0/*stack_size*/,
     1838                                         stack_size,
    18331839                                         start_routine,
    18341840                                         param,
     
    18381844  if (thread_handle == NULL) {
    18391845    wperror("CreateThread");
    1840   }
    1841   return (LispObj) ptr_to_lispobj(thread_handle);
    1842 }
    1843 #else
    1844 LispObj
     1846  } else {
     1847    won = true;
     1848    CloseHandle(thread_handle);
     1849  }
     1850  return won;
     1851}
     1852#else
     1853Boolean
    18451854create_system_thread(size_t stack_size,
    18461855                     void* stackaddr,
     
    18861895  UNLOCK(lisp_global(TCR_AREA_LOCK),current);
    18871896  pthread_attr_destroy(&attr);
    1888   return (LispObj) ptr_to_lispobj(returned_thread);
     1897  return (returned_thread != NULL);
    18891898}
    18901899#endif
     
    21262135      result = true;
    21272136#ifdef WINDOWS
    2128       /* What we really want to de hear is (something like)
     2137      /* What we really want to do here is (something like)
    21292138         forcing the thread to run quit_handler().  For now,
    2130          mark the TCR as dead and kill thw Windows thread. */
     2139         mark the TCR as dead and kill the Windows thread. */
    21312140      tcr->osid = 0;
    21322141      if (!TerminateThread((HANDLE)osid, 0)) {
     2142        CloseHandle((HANDLE)osid);
    21332143        result = false;
    21342144      } else {
     2145        CloseHandle((HANDLE)osid);
    21352146        shutdown_thread_tcr(tcr);
    21362147      }
  • trunk/source/lisp-kernel/x86-exceptions.c

    r13295 r13431  
    18381838    return SIGILL;
    18391839  case EXCEPTION_IN_PAGE_ERROR:
     1840  case STATUS_GUARD_PAGE_VIOLATION:
    18401841    return SIGBUS;
    18411842  default:
     
    36583659    int err;
    36593660
    3660 /* can't use UnMapMemory() beacuse it only uses MEM_DECOMMIT */
    3661 #ifdef WINDOWS
    3662     err = VirtualFree(base, nbytes, MEM_RELEASE);
    3663 #else
    3664     err = munmap(base, nbytes);
    3665 #endif
     3661    err = UnMapMemory(base, nbytes);
    36663662    if (err != 0)
    36673663      Fatal("munmap in delete_watched_area", "");
Note: See TracChangeset for help on using the changeset viewer.