Changeset 9556


Ignore:
Timestamp:
May 20, 2008, 9:26:07 AM (11 years ago)
Author:
gb
Message:

Do raise_thread_interrupt() for Win64.

If the thread is running foreign code when we interrupt it, we set a
bit in its tcr. (This is the same as what happens on other
platforms.) However, on Unix platforms (where this works via signals),
the delivery of a sigmal to the target thread causes any blocking
syscalls to return with EINTR (and thus usualy quickly qreturn to lisp glue
code that checks the interrupt-pending flag.)

If a thread's in an "alertable wait state", using QueueUserAPC might get
it out of that state. I'm not sure how to tell whether or not the thread's
in such as state.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/win64/lisp-kernel/thread_manager.c

    r9319 r9556  
    5353
    5454#ifdef WINDOWS
     55extern pc spentry_start, spentry_end,subprims_start,subprims_end;
     56extern pc restore_win64_context_start, restore_win64_context_end,
     57  restore_win64_context_load_rcx, restore_win64_context_iret;
     58
     59extern void interrupt_handler(int, siginfo_t *, ExceptionInformation *);
     60
    5561int
    5662raise_thread_interrupt(TCR *target)
    5763{
    58 }
     64  /* GCC doesn't align CONTEXT corrcectly */
     65  char _contextbuf[sizeof(CONTEXT)+__alignof(CONTEXT)];
     66  CONTEXT  *pcontext;
     67  HANDLE hthread = (HANDLE)(target->osid);
     68  pc where;
     69  area *cs = target->cs_area, *ts = target->cs_area;
     70  DWORD rc;
     71
     72  pcontext = (CONTEXT *)((((natural)&_contextbuf)+15)&~15);
     73  rc = SuspendThread(hthread);
     74  if (rc == -1) {
     75    return -1;
     76  }
     77  /* What if the suspend count is > 1 at this point ?  I don't think
     78     that that matters, but I'm not sure */
     79  pcontext->ContextFlags = CONTEXT_ALL;
     80  rc = GetThreadContext(hthread, pcontext);
     81  if (rc == 0) {
     82    wperror("GetThreadContext");
     83  }
     84  where = (pc)(xpPC(pcontext));
     85 
     86  if ((target->valence != TCR_STATE_LISP) ||
     87      (TCR_INTERRUPT_LEVEL(target) < 0) ||
     88      (target->unwinding != 0) ||
     89      (!((where < (pc)lisp_global(HEAP_END)) &&
     90         (where >= (pc)lisp_global(HEAP_START))) &&
     91       !((where < spentry_end) && (where >= spentry_start)) &&
     92       !((where < subprims_end) && (where >= subprims_start)) &&
     93       !((where < (pc) 0x16000) &&
     94         (where >= (pc) 0x15000)) &&
     95       !((where < (pc) (ts->high)) &&
     96         (where >= (pc) (ts->low))))) {
     97    /* If the thread's in a blocking syscall, it'd be nice to
     98       get it out of that state here. */
     99    target->interrupt_pending = (1LL << (nbits_in_word - 1LL));
     100    ResumeThread(hthread);
     101    return 0;
     102  } else {
     103    /* Thread is running lisp code with interupts enabled.  Set it
     104       so that it calls out and then returns to the context,
     105       handling any necessary pc-lusering. */
     106    LispObj foreign_rsp = (((LispObj)(target->foreign_sp))-128)&~15;
     107    CONTEXT *icontext = ((CONTEXT *) foreign_rsp) -1;
     108    icontext = (CONTEXT *)(((LispObj)icontext)&~15);
     109   
     110    *icontext = *pcontext;
     111   
     112    xpGPR(pcontext,REG_RCX) = SIGNAL_FOR_PROCESS_INTERRUPT;
     113    xpGPR(pcontext,REG_RDX) = 0;
     114    xpGPR(pcontext,REG_R8) = (LispObj) icontext;
     115    xpGPR(pcontext,REG_RSP) = ((LispObj *)icontext)-1;
     116    *(((LispObj *)icontext)-1) = (LispObj)raise_thread_interrupt;
     117    xpPC(pcontext) = (pc)interrupt_handler;
     118    SetThreadContext(hthread,pcontext);
     119    ResumeThread(hthread);
     120    return 0;
     121  }
     122}
     123
    59124#else
    60125int
     
    654719tsd_get(LispObj key)
    655720{
    656   TlsGetValue((DWORD)key);
     721  return TlsGetValue((DWORD)key);
    657722}
    658723#else
     
    11351200  tcr_cleanup(tcr);
    11361201#endif
    1137 
     1202  return NULL;
    11381203}
    11391204
     
    11811246xDisposeThread(TCR *tcr)
    11821247{
     1248  return 0;                     /* I don't think that this is ever called. */
    11831249}
    11841250#else
     
    13201386
    13211387#ifdef WINDOWS
    1322 extern pc spentry_start, spentry_end,subprims_start,subprims_end;
    1323 extern pc restore_win64_context_start, restore_win64_context_end,
    1324   restore_win64_context_load_rcx, restore_win64_context_iret;
    13251388
    13261389Boolean
Note: See TracChangeset for help on using the changeset viewer.