Skip to content

Commit

Permalink
Refactor engine structure (#273)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattwparas authored Oct 24, 2024
1 parent 565fe03 commit 9e8226f
Show file tree
Hide file tree
Showing 22 changed files with 1,202 additions and 1,151 deletions.
11 changes: 6 additions & 5 deletions cogs/r5rs.scm
Original file line number Diff line number Diff line change
Expand Up @@ -294,13 +294,14 @@

;; TODO: Adjust the below check-equals

(skip-compile (check-equal 1 (modulo 13 4))
(check-equal 1 (remainder 13 4))
(check-equal 3 (modulo -13 4))
(check-equal? "modulo positive numbers" 1 (modulo 13 4))
(check-equal? "modulo negative and positive" 3 (modulo -13 4))
(check-equal? "modulo positive and negative" -3 (modulo 13 -4))
(check-equal? "modulo both negative" -1 (modulo -13 -4))

(skip-compile (check-equal 1 (remainder 13 4))
(check-equal -1 (remainder -13 4))
(check-equal -3 (modulo 13 -4))
(check-equal 1 (remainder 13 -4))
(check-equal -1 (modulo -13 -4))
(check-equal -1 (remainder -13 -4))
(check-equal 4 (gcd 32 -36))
(check-equal 288 (lcm 32 -36)))
Expand Down
35 changes: 14 additions & 21 deletions cogs/sorting/merge-sort.scm
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,21 @@
;;; Merge two lists of numbers which are already in increasing order

(define merge-lists
(lambda (l1 l2)
(lambda (l1 l2 comparator)
(if (null? l1)
l2
(if (null? l2)
l1
(if (< (car l1) (car l2))
(cons (car l1) (merge-lists (cdr l1) l2))
(cons (car l2) (merge-lists (cdr l2) l1)))))))
(if (comparator (car l1) (car l2))
(cons (car l1) (merge-lists (cdr l1) l2 comparator))
(cons (car l2) (merge-lists (cdr l2) l1 comparator)))))))

;;; -------------------------------------------------------------------
;;; Given list l, output those tokens of l which are in even positions

(define even-numbers
(lambda (l)
(if (null? l)
'()
(if (null? (cdr l))
'()
(cons (car (cdr l)) (even-numbers (cdr (cdr l))))))))
(if (null? l) '() (if (null? (cdr l)) '() (cons (car (cdr l)) (even-numbers (cdr (cdr l))))))))

;;; -------------------------------------------------------------------
;;; Given list l, output those tokens of l which are in odd positions
Expand All @@ -31,19 +27,16 @@
(lambda (l)
(if (null? l)
'()
(if (null? (cdr l))
(list (car l))
(cons (car l) (odd-numbers (cdr (cdr l))))))))
(if (null? (cdr l)) (list (car l)) (cons (car l) (odd-numbers (cdr (cdr l))))))))

;;; ---------------------------------------------------------------------
;;; Use the procedures above to create a simple and efficient merge-sort

(define merge-sort
(lambda (l)
(if (null? l)
l
(if (null? (cdr l))
l
(merge-lists
(merge-sort (odd-numbers l))
(merge-sort (even-numbers l)))))))
(define (merge-sort l #:comparator [comparator <])
(if (null? l)
l
(if (null? (cdr l))
l
(merge-lists (merge-sort (odd-numbers l) #:comparator comparator)
(merge-sort (even-numbers l) #:comparator comparator)
comparator))))
24 changes: 12 additions & 12 deletions cogs/threads/test-threads.scm
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@

(define __module__ 'thread-test-module)

(define (spawn-concurrent-tasks)
; (define (spawn-concurrent-tasks)

(let ([tasks (time! (map (lambda (_)
(spawn-thread! (lambda ()
(time/sleep-ms 2000)
(displayln (thread::current/id)))))
(range 0 10)))])
(map (lambda (x) (thread-join! x)) tasks)))
; (let ([tasks (time! (map (lambda (_)
; (spawn-thread! (lambda ()
; (time/sleep-ms 2000)
; (displayln (thread::current/id)))))
; (range 0 10)))])
; (map (lambda (x) (thread-join! x)) tasks)))

; (error "HELLO WORLD")
; ; (error "HELLO WORLD")

(test-module
"Basic threads works"
(check-equal? "spawn-threads" (spawn-concurrent-tasks) (map (lambda (x) void) (range 0 10))))
; (test-module
; "Basic threads works"
; (check-equal? "spawn-threads" (spawn-concurrent-tasks) (map (lambda (x) void) (range 0 10))))

(spawn-concurrent-tasks)
; (spawn-concurrent-tasks)

; (define/generator (foo-bar-baz) (yield 10) (yield 20) (yield 30))
101 changes: 58 additions & 43 deletions cogs/threads/threads.scm
Original file line number Diff line number Diff line change
@@ -1,52 +1,67 @@
(require-builtin steel/time)
(require "steel/result")
(provide make-thread-pool
lock!
submit-task
block-on-task
task-done?
task-err)

(provide spawn-cancellable-thread-looping)
;;@doc
;; Lock the given lock during the duration
;; of the thunk.
(define (lock! lock thunk)
(lock-acquire! lock)
(dynamic-wind (lambda () void) (lambda () (thunk)) (lambda () (lock-release! lock))))

;; Spawns a thread, returning a handle to the sender to that thread.
; (define (message-passing)
; (define channels (make-channels))
; (define sender (list-ref channels 0))
; (define receiver (list-ref channels 1))
(struct ThreadPool (task-sender capacity thread-handles))

; ;; Worker thread, listen to requests
; (spawn-thread! (lambda ()
; ;; Process incoming requests.
; (while #true (displayln (channel->recv receiver)))
; (loop)))
(struct Task (lock done func-or-result err) #:mutable)

; sender)
;;@doc
;; Check if the given task is done
(define task-done? Task-done)

(define *CHILD_THREADS* '())
;;@doc
;; Get the err object (if any) from the given task
(define task-err Task-err)

;;@doc
;; Create a thread pool with the given capacity
(define (make-thread-pool capacity)
(define channels (channels/new))
(define sender (channels-sender channels))
(define receiver (channels-receiver channels))

;; Keep track of all of the threads currently running
(define (record-thread-handle handle)
(set! *CHILD_THREADS* (cons handle *CHILD_THREADS*)))
(define (listen-for-tasks)
(define next-task (channel/recv receiver))
(define func (Task-func-or-result next-task))

(struct CancellableThreadHandle (sender handle))
;; Does this work?
(with-handler (lambda (err) (set-Task-err! next-task err))
;; Capture exception, if it exists. Store it in the task
(lock! (Task-lock next-task)
(lambda ()
;; This should be fine, we're updating the task to be finished,
;; so we can check the progress of it
(set-Task-func-or-result! next-task (func))
(set-Task-done! next-task #t))))

(listen-for-tasks))

;; Give me back a thread pool to do some work
(ThreadPool sender
capacity
(map (lambda (_) (spawn-native-thread listen-for-tasks)) (range 0 capacity))))

;;@doc
;; Submit task to the thread pool
(define (submit-task tp func)
;; Create the task. We'll update this to done, and replace
;; the func with the proper value afterwards
(define task (Task (mutex) #f func #f))
(channel/send (ThreadPool-task-sender tp) task)
task)

;;@doc
;; Spawn a function, func, that runs on a background thread, running at the interval `delay-ms`
(define (spawn-cancellable-thread-looping func delay-ms)
;; Create the channels. We're going to cancel the thread using
;; the sender here to interrupt the receiver
(define channels (make-channels))
(define sender (list-ref channels 0))
(define receiver (list-ref channels 1))

(CancellableThreadHandle sender
(spawn-thread! (lambda ()
(while (not (~> (channel->try-recv receiver) (unwrap-ok)))
(begin
(func)
(time/sleep-ms delay-ms)))
(stdout-simple-displayln "Shutting down thread: "
(thread::current/id))))))

; (let ([tasks (map (lambda (_)
; (spawn-thread! (lambda ()
; (time/sleep-ms 2000)
; (displayln (thread::current/id))
; 1)))
; (range 0 10))])
; (displayln (map thread-join! tasks)))
;; Block the current thread on this task until it is finished.
(define (block-on-task task)
(lock! (Task-lock task) (lambda () (Task-func-or-result task))))
Loading

0 comments on commit 9e8226f

Please sign in to comment.