Ignore:
Timestamp:
Mar 11, 2006, 4:54:17 AM (14 years ago)
Author:
gb
Message:

Actually handle something (uuo_alloc()), since we can't do much without it.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ccl/lisp-kernel/x86-exceptions.c

    r2881 r3697  
    1818#include "lisp-exceptions.h"
    1919#include "lisp_globals.h"
     20#include "Threads.h"
    2021#include <ctype.h>
    2122#include <stdio.h>
     
    3334
    3435int
    35 page_size = 8192;
     36page_size = 4096;
     37
     38int
     39log2_page_size = 12;
     40
     41
     42
     43
     44int
     45gc_from_xp(ExceptionInformation *xp, signed_natural param)
     46{
     47  Bug(xp, "GC ?  Not yet ...");
     48
     49}
     50
     51void
     52update_bytes_allocated(TCR* tcr, void *cur_allocptr)
     53{
     54  BytePtr
     55    last = (BytePtr) tcr->last_allocptr,
     56    current = (BytePtr) cur_allocptr;
     57  if (last && (cur_allocptr != ((void *)VOID_ALLOCPTR))) {
     58    tcr->bytes_allocated += last-current;
     59  }
     60  tcr->last_allocptr = 0;
     61}
     62
     63
     64/*
     65  This doesn't GC; it returns true if it made enough room, false
     66  otherwise.
     67  If "extend" is true, it can try to extend the dynamic area to
     68  satisfy the request.
     69*/
     70
     71Boolean
     72new_heap_segment(ExceptionInformation *xp, natural need, Boolean extend, TCR *tcr)
     73{
     74  area *a;
     75  natural newlimit, oldlimit;
     76  natural log2_allocation_quantum = tcr->log2_allocation_quantum;
     77
     78  a  = active_dynamic_area;
     79  oldlimit = (natural) a->active;
     80  newlimit = (align_to_power_of_2(oldlimit, log2_allocation_quantum) +
     81              align_to_power_of_2(need, log2_allocation_quantum));
     82  if (newlimit > (natural) (a->high)) {
     83    if (extend) {
     84      if (! resize_dynamic_heap(a->active, (newlimit-oldlimit)+lisp_heap_gc_threshold)) {
     85        return false;
     86      }
     87    } else {
     88      return false;
     89    }
     90  }
     91  a->active = (BytePtr) newlimit;
     92  tcr->last_allocptr = (void *)newlimit;
     93  tcr->save_allocptr = (void *)newlimit;
     94  xpGPR(xp,Iallocptr) = (LispObj) newlimit;
     95  tcr->save_allocbase = (void *) oldlimit;
     96
     97  while (HeapHighWaterMark < (BytePtr)newlimit) {
     98    zero_page(HeapHighWaterMark);
     99    HeapHighWaterMark+=page_size;
     100  }
     101  return true;
     102}
     103
     104Boolean
     105allocate_object(ExceptionInformation *xp,
     106                natural bytes_needed,
     107                signed_natural disp_from_allocptr,
     108                TCR *tcr)
     109{
     110  area *a = active_dynamic_area;
     111
     112  /* Maybe do an EGC */
     113  if (a->older && lisp_global(OLDEST_EPHEMERAL)) {
     114    if (((a->active)-(a->low)) >= a->threshold) {
     115      gc_from_xp(xp, 0L);
     116    }
     117  }
     118
     119  /* Life is pretty simple if we can simply grab a segment
     120     without extending the heap.
     121  */
     122  if (new_heap_segment(xp, bytes_needed, false, tcr)) {
     123    xpGPR(xp, Iallocptr) -= disp_from_allocptr;
     124    return true;
     125  }
     126 
     127  /* It doesn't make sense to try a full GC if the object
     128     we're trying to allocate is larger than everything
     129     allocated so far.
     130  */
     131  if ((lisp_global(HEAP_END)-lisp_global(HEAP_START)) > bytes_needed) {
     132    untenure_from_area(tenured_area); /* force a full GC */
     133    gc_from_xp(xp, 0L);
     134  }
     135 
     136  /* Try again, growing the heap if necessary */
     137  if (new_heap_segment(xp, bytes_needed, true, tcr)) {
     138    xpGPR(xp, Iallocptr) -= disp_from_allocptr;
     139    return true;
     140  }
     141 
     142  return false;
     143}
     144
     145Boolean
     146handle_alloc_trap(ExceptionInformation *xp, TCR *tcr)
     147{
     148  natural cur_allocptr, bytes_needed;
     149  unsigned allocptr_tag;
     150  signed_natural disp;
     151 
     152  cur_allocptr = xpGPR(xp,Iallocptr);
     153  allocptr_tag = fulltag_of(cur_allocptr);
     154  if (allocptr_tag == fulltag_misc) {
     155    disp = xpGPR(xp,Iimm1);
     156  } else {
     157    disp = dnode_size-fulltag_cons;
     158  }
     159  bytes_needed = disp+allocptr_tag;
     160
     161  update_bytes_allocated(tcr,((BytePtr)(cur_allocptr-disp)));
     162  if (allocate_object(xp, bytes_needed, disp, tcr)) {
     163    return true;
     164  }
     165
     166  return false;
     167}
     168
     169Boolean
     170handle_exception(int signum, siginfo_t *info, ExceptionInformation  *context, TCR *tcr)
     171{
     172  pc program_counter = (pc)xpPC(context);
     173
     174  if (signum == SIGSEGV) {
     175    if ((info->si_addr) == 0) {
     176      /* Something mapped to SIGSEGV that has nothing to do with
     177         a memory fault */
     178      if (*program_counter == 0xcd) {   /* an int instruction */
     179        program_counter++;
     180        if (*program_counter == 0xc5) {
     181          if (handle_alloc_trap(context, tcr)) {
     182            xpPC(context) = (natural) (program_counter+1);
     183            return true;
     184          }
     185        }
     186      }
     187    }
     188  }
     189  return false;
     190}
     191
     192void
     193signal_handler(int signum, siginfo_t *info, ExceptionInformation  *context)
     194{
     195  xframe_list xframe_link;
     196  int old_valence;
     197  TCR* tcr = get_tcr(false);
     198
     199  if (! handle_exception(signum, info, context, tcr)) {
     200    char msg[512];
     201    snprintf(msg, sizeof(msg), "Unhandled exception %d at 0x%lx, context->regs at #x%lx", signum, xpPC(context), (natural)xpGPRvector(context));
     202    if (lisp_Debugger(context, info, signum, msg)) {
     203      SET_TCR_FLAG(tcr,TCR_FLAG_BIT_PROPAGATE_EXCEPTION);
     204    }
     205  }
     206}
     207
     208void
     209interrupt_handler (int signum, siginfo_t *info, ExceptionInformation *context)
     210{
     211  TCR *tcr = get_interrupt_tcr(false);
     212#ifdef NOTYET
     213  if (tcr) {
     214    if (TCR_INTERRUPT_LEVEL(tcr) < 0) {
     215      tcr->interrupt_pending = 1 << fixnumshift;
     216    } else {
     217      LispObj cmain = nrs_CMAIN.vcell;
     218
     219      if ((fulltag_of(cmain) == fulltag_misc) &&
     220          (header_subtag(header_of(cmain)) == subtag_macptr)) {
     221        /*
     222           This thread can (allegedly) take an interrupt now.
     223           It's tricky to do that if we're executing
     224           foreign code (especially Linuxthreads code, much
     225           of which isn't reentrant.)
     226           If we're unwinding the stack, we also want to defer
     227           the interrupt.
     228        */
     229        if ((tcr->valence != TCR_STATE_LISP) ||
     230            (tcr->unwinding != 0)) {
     231          TCR_INTERRUPT_LEVEL(tcr) = (1 << fixnumshift);
     232        } else {
     233          xframe_list xframe_link;
     234          int old_valence;
     235         
     236          pc_luser_xp(context, NULL);
     237          old_valence = prepare_to_wait_for_exception_lock(tcr, context);
     238          wait_for_exception_lock_in_handler(tcr, context, &xframe_link);
     239          PMCL_exception_handler(signum, context, tcr, info);
     240          unlock_exception_lock_in_handler(tcr);
     241          exit_signal_handler(tcr, old_valence);
     242        }
     243      }
     244    }
     245  }
     246#endif
     247}
    36248
    37249void
     
    49261}
    50262
     263
     264void
     265install_pmcl_exception_handlers()
     266{
     267 
     268  install_signal_handler(SIGILL, (__sighandler_t)signal_handler);
     269 
     270  install_signal_handler(SIGBUS,  (__sighandler_t)signal_handler);
     271  install_signal_handler(SIGSEGV, (__sighandler_t)signal_handler);
     272  install_signal_handler(SIGFPE, (__sighandler_t)signal_handler);
     273
     274 
     275  install_signal_handler(SIGNAL_FOR_PROCESS_INTERRUPT,
     276                         (__sighandler_t)interrupt_handler);
     277  signal(SIGPIPE, SIG_IGN);
     278}
     279
    51280void
    52281enable_fp_exceptions()
     
    57286exception_init()
    58287{
     288  install_pmcl_exception_handlers();
    59289}
    60290
Note: See TracChangeset for help on using the changeset viewer.