Ignore:
Timestamp:
Apr 22, 2014, 9:05:06 PM (6 years ago)
Author:
gb
Message:

pending GC notification mechanism for ARM (has been on x86 for a few
years.)

(setq ccl:*pending-gc-notification-hook* some-0-arg-function)

(set-gc-notification-threshold N)

arranges to call the value the function when free space before the
next full GC drops below N bytes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/lisp-kernel/arm-exceptions.c

    r16064 r16066  
    7878Boolean allocation_enabled = true;
    7979
     80Boolean
     81did_gc_notification_since_last_full_gc = false;
     82
    8083
    8184
     
    209212                natural bytes_needed,
    210213                signed_natural disp_from_allocptr,
    211                 TCR *tcr)
     214                TCR *tcr,
     215                Boolean *crossed_threshold)
    212216{
    213217  area *a = active_dynamic_area;
     
    223227     without extending the heap.
    224228  */
    225   if (new_heap_segment(xp, bytes_needed, false, tcr, NULL)) {
     229  if (new_heap_segment(xp, bytes_needed, false, tcr, crossed_threshold)) {
    226230    xpGPR(xp, allocptr) += disp_from_allocptr;
    227231    return true;
     
    235239    untenure_from_area(tenured_area); /* force a full GC */
    236240    gc_from_xp(xp, 0L);
     241    did_gc_notification_since_last_full_gc = false;
    237242  }
    238243 
     
    271276  xpGPR(xp,allocptr) = xpGPR(xp,allocbase) = VOID_ALLOCPTR;
    272277  handle_error(xp, bytes_needed < (128<<10) ? XNOMEM : error_alloc_failed,0, NULL);
     278}
     279
     280void
     281callback_for_gc_notification(ExceptionInformation *xp, TCR *tcr)
     282{
     283  LispObj cmain = nrs_CMAIN.vcell;
     284
     285  did_gc_notification_since_last_full_gc = true;
     286  if ((fulltag_of(cmain) == fulltag_misc) &&
     287      (header_subtag(header_of(cmain)) == subtag_macptr)) {
     288    callback_to_lisp(cmain,xp,SIGTRAP,0,NULL);
     289  }
    273290}
    274291
     
    291308    current,
    292309    initial = xpGPR(xp,arg_y);
     310  Boolean notify_pending_gc = false;
    293311
    294312  if (nconses == 0) {
    295313    /* Silly case */
    296314    xpGPR(xp,arg_z) = lisp_nil;
    297     xpGPR(xp,allocptr) = lisp_nil;
    298315    return true;
    299316  }
    300317  update_bytes_allocated(tcr, (void *)(void *) tcr->save_allocptr);
    301   if (allocate_object(xp,bytes_needed,(-bytes_needed)+fulltag_cons,tcr)) {
     318  if (allocate_object(xp,bytes_needed,(-bytes_needed)+fulltag_cons,tcr,&notify_pending_gc)) {
    302319    for (current = xpGPR(xp,allocptr);
    303320         nconses;
     
    309326    xpGPR(xp,arg_y) = xpGPR(xp,allocptr);
    310327    xpGPR(xp,allocptr)-=fulltag_cons;
     328    if (notify_pending_gc && !did_gc_notification_since_last_full_gc) {
     329      callback_for_gc_notification(xp,tcr);
     330    }
    311331  } else {
    312332    lisp_allocation_failure(xp,tcr,bytes_needed);
     
    316336
    317337Boolean
    318 handle_alloc_trap(ExceptionInformation *xp, TCR *tcr)
     338handle_alloc_trap(ExceptionInformation *xp, TCR *tcr, Boolean *notify)
    319339{
    320340  pc program_counter;
     
    356376
    357377  update_bytes_allocated(tcr,((BytePtr)(cur_allocptr-disp)));
    358   if (allocate_object(xp, bytes_needed, disp, tcr)) {
     378  if (allocate_object(xp, bytes_needed, disp, tcr, notify)) {
    359379    adjust_exception_pc(xp,4);
     380    if (notify && *notify) {
     381      pc_luser_xp(xp,tcr,NULL);
     382      callback_for_gc_notification(xp,tcr);
     383    }
    360384    return true;
    361385  }
     
    420444    xpGPR(xp, imm0) = lisp_heap_gc_threshold;
    421445    break;
     446
     447  case GC_TRAP_FUNCTION_SET_GC_NOTIFICATION_THRESHOLD:
     448    if ((signed_natural)arg >= 0) {
     449      lisp_heap_notify_threshold = arg;
     450      did_gc_notification_since_last_full_gc = false;
     451    }
     452    /* fall through */
     453
     454  case GC_TRAP_FUNCTION_GET_GC_NOTIFICATION_THRESHOLD:
     455    xpGPR(xp, imm0) = lisp_heap_notify_threshold;
     456    break;
     457
    422458
    423459  case GC_TRAP_FUNCTION_ENSURE_STATIC_CONSES:
     
    10141050
    10151051  if (IS_ALLOC_TRAP(instruction)) {
    1016     return handle_alloc_trap(xp, tcr);
     1052    Boolean did_notify = false,
     1053      *notify_ptr = &did_notify;
     1054    if (did_gc_notification_since_last_full_gc) {
     1055      notify_ptr = NULL;
     1056    }
     1057    return handle_alloc_trap(xp, tcr, notify_ptr);
    10171058  } else if ((xnum == SIGSEGV) ||
    10181059             (xnum == SIGBUS)) {
     
    17521793           VOID_ALLOCPTR */
    17531794        xpGPR(xp,allocptr) = VOID_ALLOCPTR;
     1795        tcr->save_allocptr = tcr->save_allocbase = VOID_ALLOCPTR;
    17541796      }
    17551797      return;
Note: See TracChangeset for help on using the changeset viewer.