smp: without-interrupts: README.txt begins the analysis
authorMatt Birkholz <puck@birchwood-abbey.net>
Fri, 16 Jan 2015 22:25:12 +0000 (15:25 -0700)
committerMatt Birkholz <puck@birchwood-abbey.net>
Fri, 16 Jan 2015 22:25:12 +0000 (15:25 -0700)
README.txt

index 349fe07c6b62d73fab4b869790a1498a97009c7d..e90227804814b77f24e68787cac3ad788d808229 100644 (file)
@@ -936,3 +936,254 @@ microcode modules and ./findprim.
   00000020 D Static_Primitive_Procedure_Table
 
        OK.  All read-only.
+\f
+** Interrupts
+
+The thread timer interrupt causes a processor to query for i/o and
+possibly switch tasks.  In a single-processor world, masking the timer
+produces an atomic section during which no other thread can run.  In
+an SMP world, masking the timer only ensures that the current thread
+does not get swapped off the processor.  It does NOT ensure that
+another thread running on another processor will not observe an
+incomplete (no longer atomic) change.
+
+Code that masks the timer interrupt to get an atomic section needs to
+be fixed.  To find ALL runtime system code that may need to be fixed,
+we start with the microcode primitives that manipulate the interrupts
+(masked AND pending), their callers, the callers of their callers,
+etc.  There are seven such primitives:
+
+  SET-INTERRUPT-ENABLES!
+  CLEAR-INTERRUPTS!
+  DISABLE-INTERRUPTS!
+  ENABLE-INTERRUPTS!
+  REQUEST-INTERRUPTS!
+  WITH-INTERRUPT-MASK
+  WITH-INTERRUPTS-REDUCED
+
+The following grep command was used to find callers of these
+primitives in the runtime system.  Callers of three of these callers
+(with-absolutely-no-interrupts, with-limited-interrupts and
+without-interrupts) are also included.
+
+  cd src/runtime/ && grep -inE 'set-interrupt-enables!|(clear|disable|enable|request)-interrupts!|with-interrupt-mask|with-interrupts-reduced|with-(absolutely-no|limited)-interrupts|without-interrupts' *
+
+The hits with accompanying analysis:
+
+  boot.scm:112:(define (with-absolutely-no-interrupts thunk)
+  boot.scm:113:  ((ucode-primitive with-interrupt-mask)
+  boot.scm:119:(define (without-interrupts thunk)
+  boot.scm:120:  (with-limited-interrupts interrupt-mask/gc-ok
+  boot.scm:125:(define (with-limited-interrupts limit-mask procedure)
+  boot.scm:126:  ((ucode-primitive with-interrupt-mask)
+
+  condvar.scm:192:      (without-interrupts
+  condvar.scm:212:    (without-interrupts
+
+  conpar.scm:453:            ((eq? marker-type set-interrupt-enables!)
+
+  crypto.scm:70:    (without-interrupts
+  crypto.scm:87:    (without-interrupts
+  crypto.scm:388:  (without-interrupts
+
+  emacs.scm:190:    (with-absolutely-no-interrupts
+  emacs.scm:204:       (with-absolutely-no-interrupts
+
+  ffi.scm:316:  (without-interrupts
+  ffi.scm:371: (without-interrupts
+  ffi.scm:391:       (without-interrupts
+  ffi.scm:422:  (without-interrupts
+
+  floenv.scm:143:      (without-interrupts
+  floenv.scm:156:      (without-interrupts
+
+  gc.scm:56:  (set-interrupt-enables! interrupt-enables))
+  gc.scm:98:     (with-absolutely-no-interrupts
+  gc.scm:165:  ((ucode-primitive request-interrupts! 1) interrupt-bit/after-gc)
+  gc.scm:184:  (with-absolutely-no-interrupts
+
+  gcfinal.scm:69:  (without-interrupts
+  gcfinal.scm:89:    (without-interrupts
+  gcfinal.scm:111:    (without-interrupts
+  gcfinal.scm:129:  (without-interrupts
+  gcfinal.scm:140:  (without-interrupts
+  gcfinal.scm:164:        (without-interrupts
+  gcfinal.scm:180:  (without-interrupts
+
+  gdbm.scm:61:    (without-interrupts
+
+  gencache.scm:462:               (without-interrupts
+
+  geneqht.scm:53:           (without-interrupts
+  geneqht.scm:86:          (without-interrupts (lambda () (rehash-table! table)))
+  geneqht.scm:243:(define-integrable (without-interrupts thunk)
+  geneqht.scm:244:  (let ((interrupt-mask (set-interrupt-enables! interrupt-mask/gc-ok)))
+  geneqht.scm:246:    (set-interrupt-enables! interrupt-mask)
+
+  generic.scm:104:    (without-interrupts
+  generic.scm:132:  (without-interrupts
+  generic.scm:277:      (without-interrupts
+
+  global.scm:36:  get-interrupt-enables set-interrupt-enables! with-interrupt-mask
+  global.scm:129:  (set-interrupt-enables! (fix:and limit-mask (get-interrupt-enables))))
+  global.scm:234:  (with-absolutely-no-interrupts (ucode-primitive halt))
+  global.scm:346:  (without-interrupts
+
+  hash.scm:168:    (with-absolutely-no-interrupts
+  hash.scm:213:    (with-absolutely-no-interrupts
+  hash.scm:218:                 (with-interrupt-mask interrupt-mask/gc-ok
+
+  hashtb.scm:1381:  (let ((interrupt-mask (set-interrupt-enables! interrupt-mask/gc-ok)))
+  hashtb.scm:1383:      (set-interrupt-enables! interrupt-mask)
+
+  infutl.scm:90:  (without-interrupts
+  infutl.scm:98:  (without-interrupts
+  infutl.scm:782:         (without-interrupts
+
+  intrpt.scm:60:  (clear-interrupts! 1)
+  intrpt.scm:88:  (clear-interrupts! interrupt-bit/timer)
+  intrpt.scm:96:  (clear-interrupts! interrupt-bit/suspend)
+  intrpt.scm:124:  (clear-interrupts! interrupt-bit/after-gc))
+  intrpt.scm:133:  (clear-interrupts! interrupt-bit/global-3)
+  intrpt.scm:142:  (clear-interrupts! interrupt-bit)
+  intrpt.scm:157:  (clear-interrupts! interrupt-bit/kbd)
+  intrpt.scm:200:  (without-interrupts
+
+  io.scm:96:  (without-interrupts
+  io.scm:176:    (let ((n (without-interrupts
+  io.scm:184:      (without-interrupts
+  io.scm:214:    (let ((n (without-interrupts
+  io.scm:222:      (without-interrupts
+  io.scm:297:  (without-interrupts
+  io.scm:380:  (without-interrupts
+  io.scm:385:  (without-interrupts
+  io.scm:443:  (without-interrupts
+  io.scm:480:  (without-interrupts
+  io.scm:528:  (without-interrupts
+  io.scm:665:  (let ((interrupt-mask (set-interrupt-enables! interrupt-mask/gc-ok)))
+  io.scm:675:              (set-interrupt-enables! interrupt-mask)
+  io.scm:681:              (set-interrupt-enables! interrupt-mask)
+  io.scm:686:  (let ((interrupt-mask (set-interrupt-enables! interrupt-mask/gc-ok)))
+  io.scm:696:    (set-interrupt-enables! interrupt-mask)))
+  io.scm:734:   (without-interrupts
+  io.scm:754:  (without-interrupts
+
+  make.scm:32:((ucode-primitive set-interrupt-enables!) 0)
+  make.scm:96:(define-integrable with-interrupt-mask (ucode-primitive with-interrupt-mask))
+  make.scm:107:(define-integrable set-interrupt-enables!
+  make.scm:108:  (ucode-primitive set-interrupt-enables!))
+  make.scm:137:         (with-interrupt-mask 0
+  make.scm:156:(set-interrupt-enables! #x0005)
+
+  os2graph.scm:251:    (without-interrupts
+  os2graph.scm:257:    (without-interrupts
+  os2graph.scm:266:    (without-interrupts
+  os2graph.scm:275:    (without-interrupts
+  os2graph.scm:284:    (without-interrupts
+  os2graph.scm:305:    (without-interrupts
+  os2graph.scm:319:    (without-interrupts
+  os2graph.scm:329:    (without-interrupts
+  os2graph.scm:350:    (without-interrupts
+  os2graph.scm:394:    (without-interrupts
+  os2graph.scm:407:    (without-interrupts
+  os2graph.scm:418:    (without-interrupts
+  os2graph.scm:451:    (without-interrupts
+  os2graph.scm:459:    (without-interrupts
+  os2graph.scm:772:  (without-interrupts
+  os2graph.scm:892:  (without-interrupts
+  os2graph.scm:1054:  (without-interrupts
+
+  parser-buffer.scm:383:             (without-interrupts
+
+  prgcop.scm:163:  (with-absolutely-no-interrupts thunk))
+
+  process.scm:85:  (without-interrupts
+  process.scm:107:  (without-interrupts (lambda () (%close-subprocess-i/o process))))
+  process.scm:162:          (without-interrupts
+  process.scm:186:  (without-interrupts
+  process.scm:214:  (without-interrupts
+  process.scm:235:  (without-interrupts
+
+  queue.scm:73:  (without-interrupts (lambda () (queued?/unsafe queue item))))
+  queue.scm:76:  (without-interrupts (lambda () (enqueue!/unsafe queue object))))
+  queue.scm:79:  (without-interrupts (lambda () (dequeue!/unsafe queue))))
+  queue.scm:85:             (without-interrupts
+  queue.scm:96:  (without-interrupts
+
+  random.scm:56:  (let ((mask ((ucode-primitive set-interrupt-enables!) interrupt-mask/gc-ok)))
+  random.scm:78:       ((ucode-primitive set-interrupt-enables!) mask)
+  random.scm:360:  (without-interrupts
+
+  rbtree.scm:131:             (without-interrupts
+  rbtree.scm:180:(define-integrable (without-interrupts thunk)
+  rbtree.scm:181:  (let ((interrupt-mask (set-interrupt-enables! interrupt-mask/gc-ok)))
+  rbtree.scm:183:    (set-interrupt-enables! interrupt-mask)
+  rbtree.scm:197:  (without-interrupts
+
+  rep.scm:141:                (with-interrupt-mask interrupt-mask/all
+
+  rgxcmp.scm:161:                    (without-interrupts
+  rgxcmp.scm:169:               (without-interrupts
+
+  runtime.pkg:165:       with-absolutely-no-interrupts
+  runtime.pkg:166:       with-limited-interrupts
+  runtime.pkg:167:       without-interrupts)
+  runtime.pkg:492:       set-interrupt-enables!
+  runtime.pkg:523:       with-interrupt-mask
+
+  savres.scm:54:    ((without-interrupts
+  savres.scm:85:  (with-absolutely-no-interrupts
+  savres.scm:90:         (with-interrupt-mask interrupt-mask/gc-ok
+  savres.scm:109:  (with-absolutely-no-interrupts
+  savres.scm:119:          (with-interrupt-mask interrupt-mask/gc-ok
+
+  sfile.scm:202:        (without-interrupts
+  sfile.scm:216:    (without-interrupts
+
+  string.scm:178:         (let ((mask (set-interrupt-enables! interrupt-mask/none)))
+  string.scm:199:           (set-interrupt-enables! mask)
+  string.scm:1612:  (without-interrupts
+
+  thread.scm:42:;;; they are done, and they must do this without-interrupts.  While
+  thread.scm:76:(define-integrable (without-interrupts thunk)
+  thread.scm:78:        (set-interrupt-enables!
+  thread.scm:81:      (set-interrupt-enables! interrupt-mask)
+  thread.scm:85:  (let ((interrupt-mask (set-interrupt-enables! interrupt-mask/gc-ok)))
+  thread.scm:89:      (set-interrupt-enables! interrupt-mask)
+  thread.scm:241:  ;; called without-interrupts.
+  thread.scm:252:  (without-interrupts (lambda () (%current-thread (%id)))))
+  thread.scm:259:      (without-interrupts
+  thread.scm:346:  (without-interrupts %suspend-current-thread))
+  thread.scm:375:  (without-interrupts
+  thread.scm:394:    (without-interrupts
+  thread.scm:449:  (without-interrupts
+  thread.scm:487:  (without-interrupts
+  thread.scm:510:      (without-interrupts
+  thread.scm:541:  (without-interrupts
+  thread.scm:687:         (set-interrupt-enables! interrupt-mask/all)
+  thread.scm:689:    (set-interrupt-enables! interrupt-mask/gc-ok)
+  thread.scm:1021:  (let ((interrupt-mask (set-interrupt-enables! interrupt-mask/gc-ok)))
+  thread.scm:1029:                   (set-interrupt-enables! interrupt-mask)
+  thread.scm:1031:                     (set-interrupt-enables! interrupt-mask/gc-ok)
+  thread.scm:1038:           (set-interrupt-enables! interrupt-mask)
+  thread.scm:1042:         (set-interrupt-enables! interrupt-mask)
+  thread.scm:1046:  (without-interrupts
+  thread.scm:1056:  (without-interrupts
+  thread.scm:1066:  (without-interrupts
+  thread.scm:1128:               (set-interrupt-enables! interrupt-mask/gc-ok)
+  thread.scm:1283:                  ((ucode-primitive request-interrupts! 1)
+  thread.scm:1303:     ((ucode-primitive clear-interrupts!) interrupt-bit/timer))))
+
+  uerror.scm:62:                      (set-interrupt-enables! interrupt-enables)
+  uerror.scm:75:                (set-interrupt-enables! interrupt-enables)
+  uerror.scm:418:               (set-interrupt-enables! interrupt-enables)
+
+  unpars.scm:515:  (if (with-absolutely-no-interrupts
+
+  win32-registry.scm:220:              (without-interrupts
+  win32-registry.scm:290:           (without-interrupts
+  win32-registry.scm:305:          (without-interrupts
+
+  x11graph.scm:264:  (without-interrupts
+  x11graph.scm:344:  (without-interrupts
+  x11graph.scm:449:  (without-interrupts