changelog shortlog graph tags branches changeset files file revisions raw help

Mercurial > core / annotate lisp/std/thread.lisp

changeset 227: 1741660af6e9
parent: 83e823b80219
child: 2a4f11c0e8c8
author: Richard Westhaver <ellis@rwest.io>
date: Thu, 14 Mar 2024 21:52:22 -0400
permissions: -rw-r--r--
description: clists
5
6ce26a70a11e init std
ellis <ellis@rwest.io>
parents:
diff changeset
1
 ;;; threads.lisp --- Multi-thread utilities
6ce26a70a11e init std
ellis <ellis@rwest.io>
parents:
diff changeset
2
 
6ce26a70a11e init std
ellis <ellis@rwest.io>
parents:
diff changeset
3
 ;; Threading Macros
6ce26a70a11e init std
ellis <ellis@rwest.io>
parents:
diff changeset
4
 
6ce26a70a11e init std
ellis <ellis@rwest.io>
parents:
diff changeset
5
 ;;; Commentary:
6ce26a70a11e init std
ellis <ellis@rwest.io>
parents:
diff changeset
6
 
6ce26a70a11e init std
ellis <ellis@rwest.io>
parents:
diff changeset
7
 ;; mostly yoinked from sb-thread and friends
6ce26a70a11e init std
ellis <ellis@rwest.io>
parents:
diff changeset
8
 
6ce26a70a11e init std
ellis <ellis@rwest.io>
parents:
diff changeset
9
 ;;; Code:
96
301fd45bbe73 big refactor of lisp code
ellis <ellis@rwest.io>
parents: 18
diff changeset
10
 (in-package :std)
5
6ce26a70a11e init std
ellis <ellis@rwest.io>
parents:
diff changeset
11
 
6ce26a70a11e init std
ellis <ellis@rwest.io>
parents:
diff changeset
12
 (defun thread-support-p () (member :thread-support *features*))
6ce26a70a11e init std
ellis <ellis@rwest.io>
parents:
diff changeset
13
 
6ce26a70a11e init std
ellis <ellis@rwest.io>
parents:
diff changeset
14
 (eval-when (:compile-toplevel)
6ce26a70a11e init std
ellis <ellis@rwest.io>
parents:
diff changeset
15
   (defun print-thread-message-top-level (msg)
6ce26a70a11e init std
ellis <ellis@rwest.io>
parents:
diff changeset
16
     (sb-thread:make-thread
6ce26a70a11e init std
ellis <ellis@rwest.io>
parents:
diff changeset
17
      (lambda ()
6ce26a70a11e init std
ellis <ellis@rwest.io>
parents:
diff changeset
18
        (format #.*standard-output* msg)))
6ce26a70a11e init std
ellis <ellis@rwest.io>
parents:
diff changeset
19
     nil))
118
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
20
 
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
21
 ;; this is all very unsafe. don't touch the finalizer thread plz.
119
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
22
 (defun find-thread-by-id (id)
118
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
23
   "Search for thread by ID which must be an u64. On success returns the thread itself or nil."
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
24
   (sb-thread::avlnode-data (sb-thread::avl-find id sb-thread::*all-threads*)))
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
25
 
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
26
 (defun thread-id-list ()
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
27
   (sb-thread::avltree-filter #'sb-thread::avlnode-key sb-thread::*all-threads*))
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
28
 
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
29
 (defun thread-count ()
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
30
   (sb-thread::avl-count sb-thread::*all-threads*))
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
31
 
119
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
32
 (defun make-threads (n fn &key (name "thread"))
227
Richard Westhaver <ellis@rwest.io>
parents: 222
diff changeset
33
   (declare (type fixnum n))
Richard Westhaver <ellis@rwest.io>
parents: 222
diff changeset
34
   (loop for i below n
118
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
35
         collect (make-thread fn :name (format nil "~A-~D" name i))))
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
36
 
119
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
37
 (defmacro with-threads ((idx n) &body body)
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
38
   `(make-threads ,n (lambda (,idx) (declare (ignorable ,idx)) ,@body)))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
39
 
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
40
 (defun finish-threads (&rest threads)
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
41
   (let ((threads (flatten threads)))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
42
     (unwind-protect
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
43
          (mapc #'join-thread threads)
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
44
       (dolist (thread threads)
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
45
         (when (thread-alive-p thread)
182
0e972410eb3e nu invasion
Richard Westhaver <ellis@rwest.io>
parents: 162
diff changeset
46
           (terminate-thread thread))))))
119
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
47
 
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
48
 (defun timed-join-thread (thread timeout)
227
Richard Westhaver <ellis@rwest.io>
parents: 222
diff changeset
49
   (declare (type thread thread) (type float timeout))
118
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
50
   (handler-case (sb-sys:with-deadline (:seconds timeout)
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
51
                   (join-thread thread :default :aborted))
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
52
     (sb-ext:timeout ()
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
53
       :timeout)))
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
54
 
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
55
 (defun hang ()
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
56
   (join-thread *current-thread*))
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
57
 
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
58
 (defun kill-thread (thread)
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
59
   (when (thread-alive-p thread)
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
60
     (ignore-errors
b828a3caa758 object library stuff, removed DOT - api doesnt jive.
ellis <ellis@rwest.io>
parents: 96
diff changeset
61
       (terminate-thread thread))))
119
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
62
 
227
Richard Westhaver <ellis@rwest.io>
parents: 222
diff changeset
63
 ;; (sb-vm::primitive-object-slots (sb-vm::primitive-object 'sb-vm::thread))
Richard Westhaver <ellis@rwest.io>
parents: 222
diff changeset
64
 
119
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
65
 ;; from sb-thread
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
66
 (defun dump-thread ()
227
Richard Westhaver <ellis@rwest.io>
parents: 222
diff changeset
67
   (let* ((slots (sb-vm::primitive-object-slots #1=(sb-vm::primitive-object 'sb-vm::thread)))
119
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
68
          (sap (current-thread-sap))
227
Richard Westhaver <ellis@rwest.io>
parents: 222
diff changeset
69
          (thread-obj-len (sb-vm::primitive-object-length #1#))
119
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
70
          (names (make-array thread-obj-len :initial-element "")))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
71
     (loop for slot across slots
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
72
           do
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
73
           (setf (aref names (sb-vm::slot-offset slot)) (sb-vm::slot-name slot)))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
74
     (flet ((safely-read (sap offset &aux (bits (sb-vm::sap-ref-word sap offset)))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
75
              (cond ((eql bits sb-vm:no-tls-value-marker) :no-tls-value)
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
76
                    ((eql (logand bits sb-vm:widetag-mask) sb-vm:unbound-marker-widetag) :unbound)
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
77
                    (t (sb-vm::sap-ref-lispobj sap offset))))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
78
            (show (sym val)
227
Richard Westhaver <ellis@rwest.io>
parents: 222
diff changeset
79
              (declare (type fixnum sym))
119
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
80
              (let ((*print-right-margin* 128)
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
81
                    (*print-lines* 4))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
82
                (format t " ~3d ~30a : ~s~%"
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
83
                        #+sb-thread (ash sym (- sb-vm:word-shift))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
84
                        #-sb-thread 0
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
85
                        #+sb-thread (sb-vm:symbol-from-tls-index sym)
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
86
                        #-sb-thread sym
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
87
                        val))))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
88
       (format t "~&TLS: (base=~x)~%" (sb-vm::sap-int sap))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
89
       (loop for tlsindex from sb-vm:n-word-bytes below
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
90
             #+sb-thread (ash sb-vm::*free-tls-index* sb-vm:n-fixnum-tag-bits)
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
91
             #-sb-thread (ash thread-obj-len sb-vm:word-shift)
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
92
             by sb-vm:n-word-bytes
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
93
             do
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
94
          (unless (<= sb-vm::thread-allocator-histogram-slot
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
95
                      (ash tlsindex (- sb-vm:word-shift))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
96
                      (1- sb-vm::thread-lisp-thread-slot))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
97
            (let ((thread-slot-name
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
98
                   (if (< tlsindex (ash thread-obj-len sb-vm:word-shift))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
99
                            (aref names (ash tlsindex (- sb-vm:word-shift))))))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
100
                  (if (and thread-slot-name (sb-vm::neq thread-slot-name 'sb-vm::lisp-thread))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
101
                      (format t " ~3d ~30a : #x~x~%" (ash tlsindex (- sb-vm:word-shift))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
102
                              thread-slot-name (sb-vm::sap-ref-word sap tlsindex))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
103
                      (let ((val (safely-read sap tlsindex)))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
104
                        (unless (eq val :no-tls-value)
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
105
                          (show tlsindex val)))))))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
106
       (let ((from (sb-vm::descriptor-sap sb-vm:*binding-stack-start*))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
107
             (to (sb-vm::binding-stack-pointer-sap)))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
108
         (format t "~%Binding stack: (depth ~d)~%"
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
109
                 (/ (sb-vm::sap- to from) (* sb-vm:binding-size sb-vm:n-word-bytes)))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
110
         (loop
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
111
           (when (sb-vm::sap>= from to) (return))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
112
           (let ((val (safely-read from 0))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
113
                 (sym #+sb-thread (sb-vm::sap-ref-word from sb-vm:n-word-bytes) ; a TLS index
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
114
                      #-sb-thread (sb-vm::sap-ref-lispobj from sb-vm:n-word-bytes)))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
115
             (show sym val))
85f27597cf60 castable added, still testing
ellis <ellis@rwest.io>
parents: 118
diff changeset
116
           (setq from (sb-vm::sap+ from (* sb-vm:binding-size sb-vm:n-word-bytes))))))))
162
cc74c0054bc1 prelude
ellis <ellis@rwest.io>
parents: 119
diff changeset
117
 
cc74c0054bc1 prelude
ellis <ellis@rwest.io>
parents: 119
diff changeset
118
 ;;; Tasks
227
Richard Westhaver <ellis@rwest.io>
parents: 222
diff changeset
119
 (defclass oracle () ((thread :initform *current-thread* :initarg :thread :accessor oracle-thread)))
182
0e972410eb3e nu invasion
Richard Westhaver <ellis@rwest.io>
parents: 162
diff changeset
120
 
227
Richard Westhaver <ellis@rwest.io>
parents: 222
diff changeset
121
 (defgeneric designate-oracle (host guest))
182
0e972410eb3e nu invasion
Richard Westhaver <ellis@rwest.io>
parents: 162
diff changeset
122
 
0e972410eb3e nu invasion
Richard Westhaver <ellis@rwest.io>
parents: 162
diff changeset
123
 (defstruct task-pool
0e972410eb3e nu invasion
Richard Westhaver <ellis@rwest.io>
parents: 162
diff changeset
124
   (oracle nil :type (or null oracle))
162
cc74c0054bc1 prelude
ellis <ellis@rwest.io>
parents: 119
diff changeset
125
   (jobs (sb-concurrency:make-queue :name "jobs"))
182
0e972410eb3e nu invasion
Richard Westhaver <ellis@rwest.io>
parents: 162
diff changeset
126
   (stages nil :type sequence)
162
cc74c0054bc1 prelude
ellis <ellis@rwest.io>
parents: 119
diff changeset
127
   (workers (sb-concurrency:make-mailbox :name "workers"))
cc74c0054bc1 prelude
ellis <ellis@rwest.io>
parents: 119
diff changeset
128
   (results (sb-concurrency:make-queue :name "results"))
cc74c0054bc1 prelude
ellis <ellis@rwest.io>
parents: 119
diff changeset
129
   (completed-jobs 0 :type fixnum) ;;atomic
cc74c0054bc1 prelude
ellis <ellis@rwest.io>
parents: 119
diff changeset
130
   (completed-tasks 0 :type fixnum))
cc74c0054bc1 prelude
ellis <ellis@rwest.io>
parents: 119
diff changeset
131
 
184
50594b2995f1 fix oracle method
Richard Westhaver <ellis@rwest.io>
parents: 182
diff changeset
132
 (defmethod designate-oracle ((self task-pool) guest)
50594b2995f1 fix oracle method
Richard Westhaver <ellis@rwest.io>
parents: 182
diff changeset
133
   (setf (task-pool-oracle self) guest))
50594b2995f1 fix oracle method
Richard Westhaver <ellis@rwest.io>
parents: 182
diff changeset
134
 
162
cc74c0054bc1 prelude
ellis <ellis@rwest.io>
parents: 119
diff changeset
135
 (defclass task ()
cc74c0054bc1 prelude
ellis <ellis@rwest.io>
parents: 119
diff changeset
136
   ((object :initarg :object :accessor task-object)))
cc74c0054bc1 prelude
ellis <ellis@rwest.io>
parents: 119
diff changeset
137
 
cc74c0054bc1 prelude
ellis <ellis@rwest.io>
parents: 119
diff changeset
138
 (defclass job ()
182
0e972410eb3e nu invasion
Richard Westhaver <ellis@rwest.io>
parents: 162
diff changeset
139
   ((tasks :initform (make-array 0 :element-type 'task :fill-pointer 0 :adjustable t)
0e972410eb3e nu invasion
Richard Westhaver <ellis@rwest.io>
parents: 162
diff changeset
140
           :initarg :tasks
0e972410eb3e nu invasion
Richard Westhaver <ellis@rwest.io>
parents: 162
diff changeset
141
           :accessor :tasks
222
83e823b80219 add os module
Richard Westhaver <ellis@rwest.io>
parents: 221
diff changeset
142
           :type (vector task))))
182
0e972410eb3e nu invasion
Richard Westhaver <ellis@rwest.io>
parents: 162
diff changeset
143
 (defclass stage ()
0e972410eb3e nu invasion
Richard Westhaver <ellis@rwest.io>
parents: 162
diff changeset
144
   ((jobs  :initform (make-array 0 :element-type 'task :fill-pointer 0 :adjustable t)
0e972410eb3e nu invasion
Richard Westhaver <ellis@rwest.io>
parents: 162
diff changeset
145
           :initarg :jobs
0e972410eb3e nu invasion
Richard Westhaver <ellis@rwest.io>
parents: 162
diff changeset
146
           :accessor :jobs
0e972410eb3e nu invasion
Richard Westhaver <ellis@rwest.io>
parents: 162
diff changeset
147
           :type (vector job))))