Changeset 15469 for release


Ignore:
Timestamp:
Sep 25, 2012, 5:07:47 AM (6 years ago)
Author:
gb
Message:

Propagate r15468 and friends (work around more mach_port_allocate_name()
lossage) to 1.8.

Propagate r15451 (foreign thread stack limits) to 1.8.

Location:
release/1.8/source/lisp-kernel
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • release/1.8/source/lisp-kernel/memory.c

    r15449 r15469  
    3232#include <strings.h>
    3333#endif
    34 #ifdef DARWIN64
     34#ifdef DARWIN
    3535#include <pthread.h>
    3636#endif
     
    147147ReserveMemoryForHeap(LogicalAddress want, natural totalsize)
    148148{
     149  void raise_limit(void);
    149150  LogicalAddress start;
    150151  Boolean fixed_map_ok = false;
     
    269270MapMemory(LogicalAddress addr, natural nbytes, int protection)
    270271{
     272  LogicalAddress p;
    271273#if DEBUG_MEMORY
    272274  fprintf(dbgout, "Mapping memory at 0x" LISP ", size 0x" LISP "\n", addr, nbytes);
    273275#endif
    274276#ifdef WINDOWS
    275   return VirtualAlloc(addr, nbytes, MEM_RESERVE|MEM_COMMIT, MEMPROTECT_RWX);
     277  p = VirtualAlloc(addr, nbytes, MEM_RESERVE|MEM_COMMIT, MEMPROTECT_RWX);
     278  if (p == NULL) {
     279    wperror("MapMemory");
     280  }
     281  return p;
    276282#else
    277283  {
     
    969975}
    970976
    971 #ifdef DARWIN64
     977#ifdef DARWIN
    972978/*
    973979  On 64-bit Darwin, we try to make a TCR's address serve as a Mach port
     
    989995  doesn't conflict with a mapped region (as it seems to in practice
    990996  since at least 10.5 and as it's documented to in 10.6.)
     997
     998  OSX 10.8 introduces new horrors that affect 32-bit CCL as well:
     999
     1000  mach_port_allocate_name(mach_task_self(),MACH_PORT_RIGHT_RECEIVE,n)
     1001 
     1002  returns KERN_NO_SPACE for n > ~#x09800000.  It's not known whether or
     1003  not this is intentional; even if it's a bug, it suggests that we should
     1004  probably stop trying to arrange that a TCR's address can be used as the
     1005  corresponding thread's exception port and maintain some sort of
     1006  efficient and thread-safe mapping from port to TCR.  Soon.
     1007
     1008  News flash:  mach_port_allocate_name() is not only worse than we
     1009  imagine on 10.8, but it's worse than we can imagine.  Give up.
     1010  (This means that there are no longer any constraints on TCR addresses
     1011  and we could just use malloc here, but keep some of this code around
     1012  for now.)
    9911013*/
    9921014
     
    9981020but not so much that we waste lots of 32-bit memory. */
    9991021
    1000 #define LIMIT_32_BIT (natural)(1L<<32L)
     1022
     1023
     1024
     1025/* force 16-bit alignment, just in case */
     1026typedef struct {
     1027  TCR tcr;
     1028}  __attribute__ ((aligned(16))) MTCR;
     1029
     1030
     1031
     1032void
     1033link_tcr_list(TCR *head, MTCR *buf, int n)
     1034{
     1035  TCR *prev = head, *tcr;
     1036  int i;
     1037
     1038  for (i=0; i < n; i++, buf++) {
     1039    tcr = &(buf->tcr);
     1040    prev->next = tcr;
     1041    tcr->prev = prev;
     1042    head->prev = tcr;
     1043    tcr->next = head;
     1044    prev = tcr;
     1045  }
     1046}
     1047
     1048
     1049
    10011050
    10021051void
    10031052map_tcr_cluster(TCR *head)
    10041053{
    1005   TCR *work = NULL, *prev = head;
     1054  MTCR *work = NULL;
     1055  TCR *prev = head;
    10061056  int i;
    1007   vm_address_t addr = (vm_address_t)0, nextaddr;
    1008   void *p;
    1009   vm_size_t request_size = align_to_power_of_2((TCR_CLUSTER_COUNT*sizeof(TCR)),log2_page_size), vm_size;
    1010   vm_region_basic_info_data_64_t vm_info;
    1011   mach_msg_type_number_t vm_info_size = VM_REGION_BASIC_INFO_COUNT_64;
    1012   mach_port_t vm_object_name = (mach_port_t) 0;
    1013   kern_return_t kret;
    1014 
    1015   while (1) {
    1016     nextaddr = addr;
    1017     vm_info_size = VM_REGION_BASIC_INFO_COUNT_64;
    1018     kret = vm_region_64(mach_task_self(),
    1019                         &nextaddr,
    1020                         &vm_size,
    1021                         VM_REGION_BASIC_INFO_64,
    1022                         (vm_region_info_t)&vm_info,
    1023                         &vm_info_size,
    1024                         &vm_object_name);
    1025     if (kret != KERN_SUCCESS) {
    1026       break;
    1027     }
    1028     if (addr && ((nextaddr - addr) > request_size)) {
    1029       if ((addr + request_size) > LIMIT_32_BIT) {
    1030         break;
    1031       }
    1032       p = mmap((void *)addr,
    1033                request_size,
    1034                PROT_READ|PROT_WRITE,
    1035                MAP_PRIVATE|MAP_ANON,
    1036                -1,
    1037                0);
    1038       if (p == MAP_FAILED) {
    1039         break;
    1040       } else {
    1041         if (((natural)p > LIMIT_32_BIT) ||
    1042             ((((natural)p)+request_size) > LIMIT_32_BIT)) {
    1043           munmap(p, request_size);
    1044           nextaddr = 0;
    1045           vm_size = 0;
    1046         } else {
    1047           work = (TCR *) p;
    1048           break;
    1049         }
    1050       }
    1051     }
    1052     addr = nextaddr + vm_size;   
    1053   }
    1054   if (!work) {
     1057  size_t request_size = align_to_power_of_2((TCR_CLUSTER_COUNT*sizeof(MTCR)),log2_page_size);
     1058
     1059  work = (MTCR *)mmap(NULL,
     1060                      request_size,
     1061                      PROT_READ|PROT_WRITE,
     1062                      MAP_PRIVATE|MAP_ANON,
     1063                      -1,
     1064                      0);
     1065
     1066  if (work == MAP_FAILED) {
    10551067    Fatal("Can't allocate memory for thread-local storage.", "");
    10561068  }
    1057  
    1058   for (i=0; i < TCR_CLUSTER_COUNT; i++, work++) {
    1059     prev->next = work;
    1060     work->prev = prev;
    1061     head->prev = work;
    1062     work->next = head;
    1063     prev = work;
    1064   }
     1069  link_tcr_list(head, work, TCR_CLUSTER_COUNT);
    10651070}
    10661071
     
    10791084}
    10801085
     1086
    10811087TCR *
    10821088darwin_allocate_tcr()
     
    10961102  head->next = tail;
    10971103  pthread_mutex_unlock(&darwin_tcr_lock);
     1104  memset(tcr,0,sizeof(TCR));
    10981105  return tcr;
    10991106}
  • release/1.8/source/lisp-kernel/platform-darwinx8664.h

    r15449 r15469  
    9191#include "os-darwin.h"
    9292
    93 #define DARWIN64 1
     93
  • release/1.8/source/lisp-kernel/pmcl-kernel.c

    r15239 r15469  
    319319  BytePtr lowlimit = (BytePtr) (((((natural)bottom)-size)+4095)&~4095);
    320320  area *a = new_area((BytePtr) bottom-size, bottom, AREA_CSTACK);
    321   a->hardlimit = lowlimit+CSTACK_HARDPROT;
    322   a->softlimit = a->hardlimit+CSTACK_SOFTPROT;
     321  if (size > (CSTACK_HARDPROT + CSTACK_SOFTPROT)) {
     322    a->hardlimit = lowlimit+CSTACK_HARDPROT;
     323    a->softlimit = a->hardlimit+CSTACK_SOFTPROT;
     324  } else {
     325    a->softlimit = a->hardlimit = lowlimit;
     326  }
    323327#ifdef USE_SIGALTSTACK
    324328  setup_sigaltstack(a);
  • release/1.8/source/lisp-kernel/thread_manager.c

    r15449 r15469  
    827827allocate_tcr()
    828828{
    829   TCR *tcr, *chain = NULL, *next;
     829  TCR *tcr, *next;
    830830#ifdef DARWIN
    831831  extern Boolean use_mach_exception_handling;
    832 #ifdef DARWIN64
     832#ifdef DARWIN
    833833  extern TCR* darwin_allocate_tcr(void);
    834834  extern void darwin_free_tcr(TCR *);
     
    840840#endif
    841841  for (;;) {
    842 #ifdef DARWIN64
     842#ifdef DARWIN
    843843    tcr = darwin_allocate_tcr();
    844844#else
     
    847847#ifdef DARWIN
    848848    if (use_mach_exception_handling) {
    849       thread_exception_port = (mach_port_t)((natural)tcr);
    850       kret = mach_port_allocate_name(task_self,
    851                                      MACH_PORT_RIGHT_RECEIVE,
    852                                      thread_exception_port);
    853     } else {
    854       kret = KERN_SUCCESS;
    855     }
    856 
    857     if (kret != KERN_SUCCESS) {
    858       tcr->next = chain;
    859       chain = tcr;
    860       continue;
    861     }
    862 #endif
    863     for (;chain;chain = next) {
    864       next = chain->next;
    865 #ifdef DARWIN64
    866       darwin_free_tcr(chain);
    867 #else
    868       free(chain);
    869 #endif
    870     }
     849      if (mach_port_allocate(task_self,
     850                             MACH_PORT_RIGHT_RECEIVE,
     851                             &thread_exception_port) == KERN_SUCCESS) {
     852        tcr->io_datum = (void *)((natural)thread_exception_port);
     853        associate_tcr_with_exception_port(thread_exception_port,tcr);
     854      } else {
     855        Fatal("Can't allocate Mach exception port for thread.", "");
     856      }
     857    }
     858
     859#endif
    871860    return tcr;
    872861  }
     
    13611350shutdown_thread_tcr(void *arg)
    13621351{
    1363 #ifdef DARWIN64
     1352#ifdef DARWIN
    13641353  extern void darwin_free_tcr(TCR *);
    13651354#endif
     
    14391428    tcr->interrupt_pending = 0;
    14401429    TCR_AUX(tcr)->termination_semaphore = NULL;
    1441 #if defined(HAVE_TLS) || defined(WIN_32) || defined(DARWIN64)
     1430#if defined(HAVE_TLS) || defined(WIN_32) || defined(DARWIN)
    14421431    dequeue_tcr(tcr);
    14431432#endif
     
    14551444#endif
    14561445#endif
    1457 #ifdef DARWIN64
     1446#ifdef DARWIN
    14581447    darwin_free_tcr(tcr);
    14591448#endif
     
    15441533  tcr->last_lisp_frame = (natural)(a->high);
    15451534#endif
    1546   if (!(tcr->flags & (1<<TCR_FLAG_BIT_FOREIGN))) {
    1547     TCR_AUX(tcr)->cs_limit = (LispObj)ptr_to_lispobj(a->softlimit);
    1548   }
     1535  TCR_AUX(tcr)->cs_limit = (LispObj)ptr_to_lispobj(a->softlimit);
    15491536#ifdef LINUX
    15501537#ifdef PPC
     
    23152302free_freed_tcrs ()
    23162303{
    2317 #ifdef DARWIN64
     2304#ifdef DARWIN
    23182305  extern void darwin_free_tcr(TCR *);
    23192306#endif
     
    23272314     * tcr aux vector elsewhere. */
    23282315#else
    2329 #ifdef DARWIN64
     2316#ifdef DARWIN
    23302317    darwin_free_tcr(current);
    23312318#else
  • release/1.8/source/lisp-kernel/x86-exceptions.c

    r15194 r15469  
    3535#ifdef DARWIN
    3636#include <sysexits.h>
     37#include <dlfcn.h>
     38#include <mach/machine/vm_types.h>
    3739#endif
    3840#ifndef WINDOWS
     
    9092  __asm volatile("int $0xcd");
    9193}
     94
     95#ifdef DARWIN
     96 typedef kern_return_t (*like_mach_port_get_context)(mach_port_t,mach_port_t,mach_vm_address_t *);
     97
     98typedef kern_return_t (*like_mach_port_set_context)(mach_port_t,mach_port_t,mach_vm_address_t);
     99
     100like_mach_port_get_context Pmach_port_get_context = NULL;
     101like_mach_port_set_context Pmach_port_set_context = NULL;
     102
     103Boolean use_mach_port_context_functions = false;
     104
     105void
     106darwin_early_exception_init()
     107{
     108  Pmach_port_get_context = dlsym(RTLD_DEFAULT, "mach_port_get_context");
     109  Pmach_port_set_context = dlsym(RTLD_DEFAULT, "mach_port_set_context");
     110  if ((Pmach_port_set_context != NULL) &&
     111      (Pmach_port_get_context != NULL)) {
     112    use_mach_port_context_functions = true;
     113  }
     114}
     115#endif
    92116
    93117void
     
    23282352{
    23292353  x86_early_exception_init();
     2354#ifdef DARWIN
     2355  darwin_early_exception_init();
     2356#endif
    23302357  install_pmcl_exception_handlers();
    23312358}
     
    29292956#endif
    29302957
    2931 #define TCR_FROM_EXCEPTION_PORT(p) ((TCR *)((natural)p))
    2932 #define TCR_TO_EXCEPTION_PORT(tcr) ((mach_port_t)((natural)(tcr)))
     2958#define TCR_FROM_EXCEPTION_PORT(p) find_tcr_from_exception_port(p)
     2959#define TCR_TO_EXCEPTION_PORT(t) (mach_port_name_t)((natural) (((TCR *)t)->io_datum))
     2960
    29332961
    29342962extern void pseudo_sigreturn(void);
     
    32553283#define DARWIN_EXCEPTION_HANDLER signal_handler
    32563284
     3285#define EXCEPTION_PORT_BUCKETS 109
     3286
     3287TCR *
     3288exception_port_map[EXCEPTION_PORT_BUCKETS];
     3289
     3290pthread_mutex_t
     3291exception_port_map_lock = PTHREAD_MUTEX_INITIALIZER;
     3292
     3293TCR *
     3294find_tcr_from_exception_port(mach_port_t port)
     3295{
     3296  if (use_mach_port_context_functions) {
     3297    mach_vm_address_t addr = 0;
     3298    kern_return_t kret;
     3299
     3300    kret = Pmach_port_get_context(mach_task_self(),port,&addr);
     3301    MACH_CHECK_ERROR("finding TCR from exception port",kret);
     3302    return (TCR *)((natural)addr);
     3303  } else {
     3304    TCR *tcr = NULL;
     3305    pthread_mutex_lock(&exception_port_map_lock);
     3306
     3307    tcr = exception_port_map[(unsigned)port % EXCEPTION_PORT_BUCKETS];
     3308
     3309    while (tcr) {
     3310      if (TCR_TO_EXCEPTION_PORT(tcr) == port) {
     3311        break;
     3312      }
     3313      tcr = (TCR *)tcr->pending_io_info;
     3314    }
     3315    pthread_mutex_unlock(&exception_port_map_lock);
     3316    return tcr;
     3317  }
     3318}
     3319
     3320void
     3321associate_tcr_with_exception_port(mach_port_t port, TCR *tcr)
     3322{
     3323  if (use_mach_port_context_functions) {
     3324    kern_return_t kret;
     3325   
     3326    kret = Pmach_port_set_context(mach_task_self(),port,(mach_vm_address_t)((natural)tcr));
     3327    MACH_CHECK_ERROR("associating TCR with exception port",kret);
     3328  } else {
     3329    int b = (unsigned)port % EXCEPTION_PORT_BUCKETS;
     3330    pthread_mutex_lock(&exception_port_map_lock);
     3331   
     3332    tcr->pending_io_info = (void *)(exception_port_map[b]);
     3333    exception_port_map[b] = tcr;
     3334    pthread_mutex_unlock(&exception_port_map_lock);
     3335  }
     3336}
     3337
     3338void
     3339disassociate_tcr_from_exception_port(mach_port_t port)
     3340{
     3341  if (use_mach_port_context_functions) {
     3342    TCR **prev = &(exception_port_map[(unsigned)port % EXCEPTION_PORT_BUCKETS]),
     3343      *tcr;
     3344    pthread_mutex_lock(&exception_port_map_lock);
     3345
     3346    while((tcr = *prev) != NULL) {
     3347      if (TCR_TO_EXCEPTION_PORT(tcr) == port) {
     3348        *prev = (TCR *)tcr->pending_io_info;
     3349        break;
     3350      }
     3351      prev = (TCR **)&(tcr->pending_io_info);
     3352    }
     3353    pthread_mutex_unlock(&exception_port_map_lock);
     3354  }
     3355}
     3356 
    32573357
    32583358kern_return_t
     
    33873487{
    33883488  extern boolean_t exc_server();
    3389   mach_port_t p = TCR_TO_EXCEPTION_PORT(arg);
     3489  mach_port_t p = (mach_port_t)((natural)arg);
    33903490
    33913491  mach_exception_thread = pthread_mach_thread_np(pthread_self());
     
    35913691  }
    35923692  if (use_mach_exception_handling) {
    3593     mach_port_deallocate(mach_task_self(),TCR_TO_EXCEPTION_PORT(tcr));
    3594     mach_port_destroy(mach_task_self(),TCR_TO_EXCEPTION_PORT(tcr));
     3693    mach_port_t task_self = mach_task_self(),
     3694      exception_port = TCR_TO_EXCEPTION_PORT(tcr);
     3695
     3696    disassociate_tcr_from_exception_port(exception_port);
     3697    mach_port_deallocate(task_self,exception_port);
     3698    mach_port_destroy(task_self,exception_port);
    35953699  }
    35963700}
  • release/1.8/source/lisp-kernel/x86-exceptions.h

    r14993 r15469  
    8686void callback_for_gc_notification(ExceptionInformation *xp, TCR *tcr);
    8787
     88#ifdef DARWIN
     89TCR *
     90find_tcr_from_exception_port(mach_port_t);
     91
     92void
     93associate_tcr_with_exception_port(mach_port_t, TCR *);
     94
     95void
     96disassociate_tcr_from_exception_port(mach_port_t);
     97#endif
     98
     99
    88100#endif /* X86_EXCEPTIONS_H */
    89101
Note: See TracChangeset for help on using the changeset viewer.