Changeset 15449 for release


Ignore:
Timestamp:
Aug 25, 2012, 3:35:41 AM (7 years ago)
Author:
gb
Message:

Propagate r15437-r15439 to 1.8.

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

Legend:

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

    r14295 r15449  
    3232#include <strings.h>
    3333#endif
     34#ifdef DARWIN64
     35#include <pthread.h>
     36#endif
    3437
    3538#ifndef WINDOWS
     
    946949  }
    947950}
     951
     952LogicalAddress
     953ReserveMemory(natural size)
     954{
     955  LogicalAddress p;
     956#ifdef WINDOWS
     957  p = VirtualAlloc(0,
     958                   size,
     959                   MEM_RESERVE,
     960                   PAGE_NOACCESS);
     961  return p;
     962#else
     963  p = mmap(NULL,size,PROT_NONE,MAP_PRIVATE|MAP_ANON|MAP_NORESERVE,-1,0);
     964  if (p == MAP_FAILED) {
     965    return NULL;
     966  }
     967  return p;
     968#endif
     969}
     970
     971#ifdef DARWIN64
     972/*
     973  On 64-bit Darwin, we try to make a TCR's address serve as a Mach port
     974  name, which means that it has to fit in 32 bits (and not conflict with
     975  an existing port name, but that's a separate issue.)  Darwin doesn't
     976  seem to offer means of mapping/allocating memory that's guaranteed to
     977  return a 32-bit address on 64-bit systems, and trial-and-error doesn't
     978  scale well.
     979 
     980  Since it's a PITA to allocate 32-bit TCR pointers, we never free them
     981  once we've done so.  (We maintain a queue of "freed" TCRs but never
     982  unmap the memory.)  When we need to allocate TCR pointers, we try to
     983  allocate substantially more than we need.
     984
     985  The bulk allocation works by scanning the task's mapped memory
     986  regions until a free region of appropriate size is found, then
     987  mapping that region (without the dangerous use of MAP_FIXED).  This
     988  will win if OSX's mmap() tries to honor the suggested address if it
     989  doesn't conflict with a mapped region (as it seems to in practice
     990  since at least 10.5 and as it's documented to in 10.6.)
     991*/
     992
     993pthread_mutex_t darwin_tcr_lock = PTHREAD_MUTEX_INITIALIZER;
     994
     995TCR _free_tcr_queue, *darwin_tcr_freelist=&_free_tcr_queue;
     996
     997#define TCR_CLUSTER_COUNT 1024   /* Enough that we allocate clusters rarely,
     998but not so much that we waste lots of 32-bit memory. */
     999
     1000#define LIMIT_32_BIT (natural)(1L<<32L)
     1001
     1002void
     1003map_tcr_cluster(TCR *head)
     1004{
     1005  TCR *work = NULL, *prev = head;
     1006  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) {
     1055    Fatal("Can't allocate memory for thread-local storage.", "");
     1056  }
     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  }
     1065}
     1066
     1067void
     1068darwin_free_tcr(TCR *tcr)
     1069{
     1070  TCR  *head = darwin_tcr_freelist, *tail;
     1071
     1072  pthread_mutex_lock(&darwin_tcr_lock);
     1073  tail = head->prev;
     1074  tail->next = tcr;
     1075  head->prev = tcr;
     1076  tcr->prev = tail;
     1077  tcr->next = head;
     1078  pthread_mutex_unlock(&darwin_tcr_lock);
     1079}
     1080
     1081TCR *
     1082darwin_allocate_tcr()
     1083{
     1084  TCR  *head = darwin_tcr_freelist, *tail, *tcr;
     1085  pthread_mutex_lock(&darwin_tcr_lock);
     1086  if (head->next == NULL) { /* First time */
     1087    head->next = head->prev = head;
     1088  }
     1089
     1090  if (head->next == head) {
     1091    map_tcr_cluster(head);
     1092  }
     1093  tcr = head->next;
     1094  tail = tcr->next;
     1095  tail->prev = head;
     1096  head->next = tail;
     1097  pthread_mutex_unlock(&darwin_tcr_lock);
     1098  return tcr;
     1099}
     1100 
     1101
     1102
     1103
     1104#endif
  • release/1.8/source/lisp-kernel/platform-darwinx8664.h

    r15147 r15449  
    9090
    9191#include "os-darwin.h"
     92
     93#define DARWIN64 1
  • release/1.8/source/lisp-kernel/thread_manager.c

    r15202 r15449  
    830830#ifdef DARWIN
    831831  extern Boolean use_mach_exception_handling;
     832#ifdef DARWIN64
     833  extern TCR* darwin_allocate_tcr(void);
     834  extern void darwin_free_tcr(TCR *);
     835#endif
    832836  kern_return_t kret;
    833837  mach_port_t
     
    836840#endif
    837841  for (;;) {
     842#ifdef DARWIN64
     843    tcr = darwin_allocate_tcr();
     844#else
    838845    tcr = calloc(1, sizeof(TCR));
     846#endif
    839847#ifdef DARWIN
    840 #if WORD_SIZE == 64
    841     if (((unsigned)((natural)tcr)) != ((natural)tcr)) {
    842       tcr->next = chain;
    843       chain = tcr;
    844       continue;
    845     }
    846 #endif
    847848    if (use_mach_exception_handling) {
    848849      thread_exception_port = (mach_port_t)((natural)tcr);
     
    862863    for (;chain;chain = next) {
    863864      next = chain->next;
     865#ifdef DARWIN64
     866      darwin_free_tcr(chain);
     867#else
    864868      free(chain);
     869#endif
    865870    }
    866871    return tcr;
     
    13561361shutdown_thread_tcr(void *arg)
    13571362{
     1363#ifdef DARWIN64
     1364  extern void darwin_free_tcr(TCR *);
     1365#endif
    13581366  TCR *tcr = TCR_FROM_TSD(arg),*current=get_tcr(0);
    13591367
     
    14311439    tcr->interrupt_pending = 0;
    14321440    TCR_AUX(tcr)->termination_semaphore = NULL;
    1433 #if defined(HAVE_TLS) || defined(WIN_32)
     1441#if defined(HAVE_TLS) || defined(WIN_32) || defined(DARWIN64)
    14341442    dequeue_tcr(tcr);
    14351443#endif
     
    14461454    tcr->aux = NULL;
    14471455#endif
     1456#endif
     1457#ifdef DARWIN64
     1458    darwin_free_tcr(tcr);
    14481459#endif
    14491460    UNLOCK(lisp_global(TCR_AREA_LOCK),current);
     
    17501761  tcr_cleanup(tcr);
    17511762#endif
     1763  return NULL;
    17521764}
    17531765
     
    23032315free_freed_tcrs ()
    23042316{
     2317#ifdef DARWIN64
     2318  extern void darwin_free_tcr(TCR *);
     2319#endif
    23052320  TCR *current, *next;
    23062321
     
    23122327     * tcr aux vector elsewhere. */
    23132328#else
     2329#ifdef DARWIN64
     2330    darwin_free_tcr(current);
     2331#else
    23142332    free(current);
     2333#endif
    23152334#endif
    23162335#endif
Note: See TracChangeset for help on using the changeset viewer.