Fuzion Logo
fuzion-lang.dev — The Fuzion Language Portal
JavaScript seems to be disabled. Functionality is limited.

2026-06-08: Fuzion June Update

Last month brought Fuzion a little closer to providing fearless concurrency by restricting concurrent accesses to mutate effects that a thread-safe. Feeze now shows wake up between threads, helping understand what is happening.

  • General
    • Fuzion release 0.096 was built (#7120), release 0.097 development phase started (#7121)

  • Base library
    • New library features

      • add fuzion.runtime.trace to add DTRACE_PROBEs to Fuzion code that can be seen by Linux performance monitoring tools like feeze (#7094, #7115, #7102)

      • Added fearless concurrency support by adding thread-awareness to mutate effect as follows: A new feature mutate.exclusive ensures that code that modifies mutable fields is protected from races of concurrent modifications by other threads. We can hence create code like

          # an integer counter that is modified using mutate effect M
          counter(M type : mutate) is
        
            # the current value
            private val := M.env.new 0
        
            # increment the value by 1
            increment =>
              # exclusive to permit concurrent increments
              M.env.exclusive ()->
                val <- val+1
        
            # read the current value
            read =>
              # exclusive to forbib reordering in case of concurrent increments
              M.env.exclusive ()->
                val.get
                      
        A normal mutate type may not be shared between threads, so exclusive does not perform any expensive thread synchronization. We can use counter as follows:
          # declare and instate our own mutate effect
          my_mutate : mutate is
        
          my_mutate ! ()->
        
            # create counter using my_mutate effect
            cnt := counter my_mutate
        
            for i in 1 .. 10000 do
              if i %% 7
                cnt.increment
        
            say "{cnt.read} multiplies of 7 found"
                      
        However, trying to optimize this code using parallel threads as follows
          my_mutate ! ()->
        
            cnt := counter my_mutate
        
            threads := array 10 n->
              concur.threads.env.spawn ()->
                b := n*1000
                for i in b+1 .. b+1000 do
                  if i %% 7
                    cnt.increment
            threads.for_each t->t.join
        
            say "{cnt.read} multiplies of 7 found"
                      
        will result in an error since my_mutate is not thread-safe. We can fix this with a single line-change
          my_mutate : concur.blocking_mutate is
                      
        Which will use a mutex to make accesses exclusive and hence thread-safe (#7030), (#7067).

      • Added mutate.wait and mutate.exclusive_when to wait for a condition before entering an exclusive section (#7070)

        This can be used in the previous example to add a feature to counter that waits for the counter to reach a given value n:

            wait_for(n i32) =>
              M.env.exclusive_when ()->val>=n ()->val
                      
        This code blocks until the given condition val>=n is met and then exclusively returns the value by running the lambda ()->val.

        This can now be used, e.g., by a thread that reports about the current progress

            progress := concur.threads.env.spawn ()->
              for prev := 0, next
                  next := cnt.wait_for prev+1
              while next < 1400
                say "found $next"
                      
        Unlike Java's wait/notify/notifyAll, the notification here happens automatically and wake ups are only done if the condition is actually met.

      • Added a thread-safe ring buffer container.Ring_Buffer using mutate.exclusive as part of the mutate changes, removed Circular_Buffer (#7030, #7067 #7057, #7058)

      • add defer effect to add code to be executed when the effect is de-instated (#7041)

      • implement switch.type.return (#7055)

      • bool: add as_trit feature (#7097)

      • time/histogram: make histogram_mutate public for use in other threads (#7127)

    • Changed library features

      • adjust visibility of handles2 to fix flang_dev example (#7103)

      • list: redef finite to yes if cycled list is empty (#7092)

      • fix state effect that did not work when instated using infix ! (#7063)

      • made array2 and array3 equatable and hashable (#7095)

      • Use less_than_or_equal instead of less_or_equal (#7083)

      • Use map to orderable type instead of comparator for sorting (#7110)

          fruits := ["kiwi", "apple", "pear", "peach", "banana"]
          say <| fruits.sort_by (a,b -> a.byte_count <= b.byte_count)
                      
        we can now use
          fruits := ["kiwi", "apple", "pear", "peach", "banana"]
          say <| fruits.sort_by (.byte_count)
                      

      • Sequence: stricter postcondition for cycle (#7105)

    • Removed library features

      • remove effect.type.return (#7038)

  • Other library modules
    • concur module

      • rename thread as Thread (#7084)

      • sync: add check to ensure wait and signal never fail (#7081)

      • thread: keep track of scheduling policy and priority (#7099)

      • thread: synchronize set_affinity (#7106)

    • net module

      • net/connection: instantiate mutate effect inside thread (#7074)

  • Front end
    • Call.TRUE/FALSE, remove redundant overrides (#7076)

    • fix check-condition failure, due to failure in resolving select-call (#7114)

    • Fix underline range for interpolated String literals in error msg (#7085)

    • setFunctionReturnType in loop only when successBlock is present (#7113)

    • change checkLegalThisType to also check outer for legality (#7080)

    • cleanup handDownThroughInheritsCalls (#7042)

    • fix calling post-condition of redefined feature (#7052)

    • normalize SourceFile paths (#7096)

  • Monomorphization/DFA
    • dfa: setField, check that written value matches expected clazz (#7017)

  • Middle end
    • ir: minor code simplification (#7053)

    • fuir: add impl restriction test, for illegally inherited fixed features (#7039)

    • fuir: isUnitType for field clazzes, change result to false (#7019)

  • Runtime System
    • include/posix: fzE_thread_create: set default policy and priority (#7086)

  • Backends
    • JVM backend

      • sys/thread: fix set_affinity0 intrinsic in JVM backend (#7100)

    • Interpreter backend

      • be/interpreter: relax precondition in LValue (#7078)

      • be/int: Layout add method fieldSize (#7034)

  • Windows
    • win: implement fzE_thread_current (#7054)

  • Tests
    • tests: wolfssl, uncomment now working code (#7093)

  • Build Infrastructure
    • Dockerfile: Add installation of systemtap-sdt-dev (#7104)

    • try fix github release action, set immutableCreate to true (#7119)

  • Documentation
    • Modified Jitter to run on another thread with high priority. (#7040)

  • Fuzion Webserver
    • src/run: adjust how mutate is instated in thread pool (#414)

  • Feeze
    • The size of the recorded data was reduce by a factor of approximately 4 by shrinking the size of one recorded event from 64 bytes down to 16 bytes. This permits longer records with the same buffer size (commit #ce21589, commit #52c55d8).

    • Support SCHED_WAKING events and show arrows from the thread that caused the wake up (commit #fa4ff42). This illustrates quite nicely how thread interactions propagate:

      feeze showing threads waking up one another in a complex scenario!'

    • Support display of user events in Fuzion code added via calls like fuzion.runtime.trace "Hello" (commit #070101b)

      feeze showing user events 'Hello' and 'World!'

Cheers,

--The Fuzion Team.

last changed: 2026-06-09