PreviousUpNext

15.3.474  src/lib/std/src/hostthread.api

# hostthread.api
#
# [ This is a low-level interface;  Mythryl application programmers  
#   in search of concurrency should use threadkit instead.  

#   The hostthread library is intended mainly as support for library bindings 
#   to  Gtk, OpenGL and the like, so that they can block their own  
#   hostthread without stopping threadkit execution dead in the water. 

#   It might also be useful for gaining parallelism in CPU-intensive 
#   apps like mandelbrot-set viewers or raytracers or such. 

#   hostthread is a minefield of potential deadlocks, race conditions and  
#   datastructure corruption, so it should be used only when absolutely  
#   needed, and then only as minimally, simply and carefully as practical. 
# ]
#
# For background see the docs at the bottom of

#     src/c/hostthread/hostthread-on-posix-threads.c

# Compiled by:
#     src/lib/std/src/standard-core.sublib


# Compiled by:
#     src/lib/std/src/standard-core.sublib

stipulate
    package fat =  fate;                                                # fate                                  is from   src/lib/std/src/nj/fate.pkg
    package ip  =  interprocess_signals;                                # interprocess_signals                  is from   src/lib/std/src/nj/interprocess-signals.pkg
    package w1u =  one_word_unt_guts;                                   # one_word_unt_guts                     is from   src/lib/std/src/one-word-unt-guts.pkg
herein

    # This api is implemented in:
    #
    #     src/lib/std/src/hostthread.pkg
    #
    api Hostthread {
        #
        # This facility has its roots in:
        #
        #       A Portable Multiprocessor Interface for Standard ML of New Jersey 
        #       Morrisett + Tolmach 1992 31p 
        #       http://handle.dtic.mil/100.2/ADA255639
        #       http://mythryl.org/pub/pml/a-portable-multiprocessor-interface-for-smlnj-morrisett-tolmach-1992.ps 
        #
        # It has evolved significantly since then. :-)
        #
        # For reference documentation on the posix-threads call semantics see:
        #
        #     http://pubs.opengroup.org/onlinepubs/007904975/basedefs/hostthread.h.html
        #
        # For one introductory tutorial see:
        #
        #    https://computing.llnl.gov/tutorials/hostthreads/

        # We present posix-theads, barriers, condition variables
        # and mutexes as opaque values to our client packages:
        #
        Hostthread;
        Barrier;
        Condvar;
        Mutex;

        Try_Mutex_Result =  ACQUIRED_MUTEX | MUTEX_WAS_UNAVAILABLE;

        exception MAKE_PTRHEAD;

        get_hostthread_ptid:            Void -> w1u::Unt;
        get_cpu_core_count:             Void -> Int;                                    # On posix this just does   posixlib::sysconf  "NPROCESSORS_ONLN";
        #
        get_hostthread:                 Void -> Hostthread;                             # Get current hostthread.
        get_hostthread_name:            Hostthread -> String;                           # Text name for hostthread, purely for human consumption.
        set_hostthread_name:            String -> Void;                                 # Set name of current hostthread. Intended to be done immediately after spawn_hostthread.
        hostthread_to_int:              Hostthread -> Int;                              # Expose underlying implemention, for clients which want to use it as a key or index.
        #
        spawn_hostthread:               (Void -> Void) -> Hostthread;
        join_hostthread:                Hostthread -> Void;                             # Via pthread_join().
        signal_hostthread:              (Hostthread, Int) -> Void;                      # Via pthread_kill(). The 'Int' gives the signal; it should be from  interprocess_signals::signal_to_int.               interprocess_signals    is from   src/lib/std/src/nj/interprocess-signals.pkg
        hostthread_exit:                Void -> X;

        # Mutual-exclusion locks:
        #
        make_mutex:             Void -> Mutex;                                          # Allocate a mutex.
        free_mutex:             Mutex -> Void;                                          # Free a mutex. (Garbage collection won't do this because of C-side resources allocated.)
        acquire_mutex:          Mutex -> Void;                                          # Acquire exclusive control of mutex. All other hostthreads attempting this will block until we release it.
        release_mutex:          Mutex -> Void;                                          # Relinquish exclusive control of mutex, allowing other hostthreads blocked on it to acquire it.
        try_mutex:              Mutex -> Try_Mutex_Result;                              # Nonblocking version of acquire_mutex.
        with_mutex_do:          Mutex -> (Void -> X) -> X;                              # Small convenience fn to acquire mutex, hold it for the duration of thunk evaluation, and reliably release it when done.

        # Condition variables:
        #
        make_condvar:           Void -> Condvar;
        free_condvar:           Condvar -> Void;
        wait_on_condvar:        (Condvar, Mutex) -> Void;
        signal_condvar:         Condvar -> Void;
        broadcast_condvar:      Condvar -> Void;

        # Barriers -- nobody proceeds until everyone proceeds:
        #
        make_barrier:           Void -> Barrier;
        free_barrier:           Barrier -> Void;
        set_barrier:            { barrier: Barrier, threads: Int } -> Void;             # 'threads' is number of threads which must arrive at barrier before it will release them.
        wait_on_barrier:        Barrier -> Bool;                                        # Exactly one hostthread waiting at barrier gets TRUE value.






# Temporary debug hack:
mutex_to_int: Mutex -> Int;
    };
end;

## Code by Jeff Prothero: Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext