Browse Source

Convert treemap filesystem to task system

The code is so much cleaner. There's at least one issue with
it (getting stuck) but I don't think it's with the task system, I
think it's with my stuff.
filter-focus
Macoy Madson 1 year ago
parent
commit
76922894fd
  1. 155
      src/TreemapFileSystem.cake

155
src/TreemapFileSystem.cake

@ -1,6 +1,6 @@
(import
"FileHelper.cake" "FileSystem.cake" "Treemap.cake" "TreemapOpenGL.cake" "Utilities.cake"
"Dictionary.cake" "SDL.cake" &with-decls "Math.cake"
"Dictionary.cake" "SDL.cake" "TaskSystem.cake" &with-decls "Math.cake"
&comptime-only "CHelpers.cake")
(comptime-cond
@ -10,12 +10,15 @@
(true
(import "ProfilerNull.cake")))
(c-import "<cstdio>")
(c-import "<stdio.h>")
(c-import "SDL_thread.h" "SDL_mutex.h" "SDL_timer.h"
(c-import "SDL_thread.h" "SDL_timer.h"
;; For Uint64
&with-decls "SDL_stdinc.h")
;; TODO Need infect
(module-use-sdl-build-options)
(add-c-search-directory-module "Dependencies/enkiTS/src")
(forward-declare (struct treemap-file-system-multithreaded-state))
@ -72,20 +75,20 @@
(dynarray-free (path state > classifications))
(free state))
(defenum treemap-running-state
treemap-running-state-not-started
treemap-running-state-working
treemap-running-state-done)
(defstruct-local treemap-file-system-multithreaded-state
current-treemap-state-dir dynstring
current-treemap-state (* treemap-file-system-state)
future-treemap-state-dir dynstring
future-treemap-scan-start-time Uint64
refresh-requested bool
future-treemap-state (* treemap-file-system-state)
future-treemap-thread-handle (* SDL_Thread)
future-state-thread-should-run SDL_atomic_t ;; For shutting down worker
future-state-thread-work-done bool ;; Tracked by main thread once it gets the lock again
future-state-thread-state treemap-running-state
future-state-lock (* SDL_mutex)
colorizers (* file-colorizer)) ;; Dynarray, used only by the future state thread
@ -95,28 +98,17 @@
(memset new-state 0 (sizeof (type treemap-file-system-multithreaded-state)))
(set (path new-state > current-treemap-state-dir) null)
(set (path new-state > current-treemap-state) (create-treemap-file-system-state))
(set (path new-state > future-treemap-thread-handle) null)
(set (path new-state > future-treemap-state-dir) null)
(set (path new-state > future-treemap-state) (create-treemap-file-system-state))
(set (path new-state > future-state-lock) (SDL_CreateMutex))
(return new-state))
(defun free-treemap-file-system-multithreaded-state (state (* treemap-file-system-multithreaded-state))
(SDL_LockMutex (path state > future-state-lock))
(when (path state > future-treemap-thread-handle)
(SDL_AtomicSet (addr (path state > future-state-thread-should-run)) 0)
(var status int 0)
(SDL_WaitThread (path state > future-treemap-thread-handle) (addr status)))
(dynarray-free (path state > current-treemap-state-dir))
(free-treemap-file-system-state (path state > current-treemap-state))
(dynarray-free (path state > future-treemap-state-dir))
(free-treemap-file-system-state (path state > future-treemap-state))
(dynarray-free (path state > colorizers))
(SDL_UnlockMutex (path state > future-state-lock))
(SDL_DestroyMutex (path state > future-state-lock)))
(dynarray-free (path state > colorizers)))
(defun-local treemap-scan-filesystem-recursive (directory-to-scan (* (const char))
directories-out (* (* treemap-directory))
@ -333,7 +325,7 @@
(dynarray-push (deref paths-out) (path this-entry-details > path))
(each-in-range 4 coord
(dynarray-push (deref coordinates-out)
(at (+ (* 4 i) coord) this-dir-coordinates)))))))
(at (+ (* 4 i) coord) this-dir-coordinates)))))))
(scope ;; For setting sane pre-allocations
(fprintf stderr "Final capacity of this-directory-entries: %d\n"
@ -491,37 +483,36 @@
(set (deref picked-index-out) -1)
(return null))
(defun-local treemap-future-state-needs-update (state (* treemap-file-system-multithreaded-state)
&return bool)
(return (and (path state > future-treemap-state-dir)
(or (not (path state > current-treemap-state-dir))
(!= 0 (strcmp (path state > future-treemap-state-dir)
(path state > current-treemap-state-dir)))
(and
(not (path state > future-state-thread-work-done))
(path state > refresh-requested))))))
(defun-local treemap-update-future-state-worker-thread (user-data (* void) &return int)
(var-cast-to state (* treemap-file-system-multithreaded-state) user-data)
(while (SDL_AtomicGet (addr (path state > future-state-thread-should-run)))
;; TODO This sucks
(SDL_LockMutex (path state > future-state-lock))
(when (treemap-future-state-needs-update state)
(fprintf stderr "Doing job\n")
(update-treemap-with-file-sizes-internal
(path state > future-treemap-state-dir)
(path state > future-treemap-state)
(path state > colorizers))
(set (path state > future-state-thread-work-done) true)
(fprintf stderr "Done doing job\n"))
(SDL_UnlockMutex (path state > future-state-lock))
(SDL_Delay 25))
(return 0))
(defenum treemap-running-state
treemap-running-state-not-started
treemap-running-state-working
treemap-running-state-done)
(def-task treemap-update-future-state-task (state (* treemap-file-system-multithreaded-state))
(fprintf stderr "Doing job\n")
(update-treemap-with-file-sizes-internal
(path state > future-treemap-state-dir)
(path state > future-treemap-state)
(path state > colorizers)))
(def-task treemap-update-future-state-done (state (* treemap-file-system-multithreaded-state))
;; The swap of future->current always happens on the main thread
(var temp-state (* treemap-file-system-state) (path state > current-treemap-state))
(set (path state > current-treemap-state) (path state > future-treemap-state))
(set (path state > future-treemap-state) temp-state)
(dynarray-clear (path state > current-treemap-state-dir))
(dynstring-append (addr (path state > current-treemap-state-dir))
(path state > future-treemap-state-dir))
(var classification-colors (* float) null)
(dynarray-set-length classification-colors (* 3 (dynarray-length (path state > colorizers))))
(unless (dynarray-length classification-colors) (dynarray-set-length classification-colors 3))
(each-item-addr-in-dynarray (path state > colorizers) colorizer-index colorizer (* file-colorizer)
(memcpy (addr (at (* 3 colorizer-index) classification-colors))
(path colorizer > color)
(sizeof (path colorizer > color))))
(treemap-opengl-update (path state > current-treemap-state > coordinates)
(/ (dynarray-length (path state > current-treemap-state > coordinates)) 4)
(path state > current-treemap-state > classifications)
classification-colors)
(dynarray-free classification-colors)
(set (path state > future-state-thread-state) treemap-running-state-done))
(defun treemap-update-state (state (* treemap-file-system-multithreaded-state)
desired-dir (* (const char))
@ -529,80 +520,34 @@
layout-display-size vec3
num-entries-scanned-out (* (unsigned int))
&return treemap-running-state)
;; Worker is working
(unless (= 0 (SDL_TryLockMutex (path state > future-state-lock)))
(when (and num-entries-scanned-out ;; Get count "from" worker thread
(not (path state > future-state-thread-work-done)))
(when (= treemap-running-state-working (path state > future-state-thread-state))
(when num-entries-scanned-out ;; Get count "from" worker thread
(set (deref num-entries-scanned-out)
(type-cast
(SDL_AtomicGet (addr (path state > future-treemap-state > num-entries-scanned)))
(unsigned int))))
;; TODO This was in effort to prevent flickering on the off chance that the mutex was locked at
;; just the right time, but it doesn't quite work
(return (? (not (path state > future-state-thread-work-done))
treemap-running-state-working
treemap-running-state-done)))
;; Work just finished
(when (path state > future-state-thread-work-done)
;; The swap of future->current always happens on the main thread
(var temp-state (* treemap-file-system-state) (path state > current-treemap-state))
(set (path state > current-treemap-state) (path state > future-treemap-state))
(set (path state > future-treemap-state) temp-state)
(dynarray-clear (path state > current-treemap-state-dir))
(dynstring-append (addr (path state > current-treemap-state-dir))
(path state > future-treemap-state-dir))
(var classification-colors (* float) null)
(dynarray-set-length classification-colors (* 3 (dynarray-length (path state > colorizers))))
(unless (dynarray-length classification-colors) (dynarray-set-length classification-colors 3))
(each-item-addr-in-dynarray (path state > colorizers) colorizer-index colorizer (* file-colorizer)
(memcpy (addr (at (* 3 colorizer-index) classification-colors))
(path colorizer > color)
(sizeof (path colorizer > color))))
(treemap-opengl-update (path state > current-treemap-state > coordinates)
(/ (dynarray-length (path state > current-treemap-state > coordinates)) 4)
(path state > current-treemap-state > classifications)
classification-colors)
(dynarray-free classification-colors)
(set (path state > future-state-thread-state) treemap-running-state-done)
(set (path state > refresh-requested) false)
(set (path state > future-state-thread-work-done) false))
(return (path state > future-state-thread-state)))
;; Already displaying desired. Nothing to do
(when (and desired-dir (path state > current-treemap-state-dir))
(when (and (= 0 (strcmp desired-dir (path state > current-treemap-state-dir)))
(<= request-refresh-time (path state > future-treemap-scan-start-time)))
(SDL_UnlockMutex (path state > future-state-lock))
(return treemap-running-state-done)))
;; Future state is being computed for the desired dir. Nothing to start
(when (= (path state > future-state-thread-state)
treemap-running-state-working)
(SDL_UnlockMutex (path state > future-state-lock))
(return treemap-running-state-working))
(fprintf stderr "Start task to get dir %s\n" desired-dir)
;; Lazy create work thread
(unless (path state > future-treemap-thread-handle)
(SDL_AtomicSet (addr (path state > future-state-thread-should-run)) 1)
(set (path state > future-treemap-thread-handle)
(SDL_CreateThread treemap-update-future-state-worker-thread
"TreemapFutureState" state)))
(set (path state > future-treemap-scan-start-time) (SDL_GetPerformanceCounter))
(set (path state > refresh-requested) true)
(set (path state > future-state-thread-state) treemap-running-state-working)
(dynarray-clear (path state > future-treemap-state-dir))
(dynstring-append (addr (path state > future-treemap-state-dir)) desired-dir)
(set (path state > future-state-thread-work-done) false)
;; Copy colorizer for the other thread
(dynarray-set-length (path state > colorizers) (dynarray-length g-file-colorizers))
(memcpy (path state > colorizers) g-file-colorizers (dynarray-length-sizeof g-file-colorizers))
(set (path state > future-treemap-state > layout-display-size) layout-display-size)
(SDL_AtomicSet (addr (path state > future-treemap-state > num-entries-scanned)) 0)
(SDL_UnlockMutex (path state > future-state-lock))
(task-system-execute
(treemap-update-future-state-task state)
(treemap-update-future-state-done :pin-to-main-thread state))
(return treemap-running-state-working))

Loading…
Cancel
Save