#include #include "bits/algorithm.hfa" #include "bits/locks.hfa" #include "bits/containers.hfa" #include "invoke.h" #include "time_t.hfa" #include "time.hfa" #include /////////////////////////////////////////////////////////////////// //// is_blocking_lock /////////////////////////////////////////////////////////////////// trait is_blocking_lock(dtype L | sized(L)) { void add_( L &, struct $thread * ); // For synchronization locks to use when acquiring void remove_( L & ); // For synchronization locks to use when releasing size_t get_recursion_count( L & ); // to get recursion count for cond lock to reset after waking void set_recursion_count( L &, size_t recursion ); // to set recursion count after getting signalled; }; /////////////////////////////////////////////////////////////////// //// info_thread /////////////////////////////////////////////////////////////////// forall(dtype L | is_blocking_lock(L)) { struct info_thread { struct $thread * t; uintptr_t info; info_thread(L) * next; L * lock; }; void ?{}( info_thread(L) & this, $thread * t ); void ?{}( info_thread(L) & this, $thread * t, uintptr_t info ); void ^?{}( info_thread(L) & this ); info_thread(L) *& get_next( info_thread(L) & this ); } /////////////////////////////////////////////////////////////////// //// Blocking Locks /////////////////////////////////////////////////////////////////// struct blocking_lock { // Spin lock used for mutual exclusion __spinlock_t lock; // List of blocked threads __queue_t( struct $thread ) blocked_threads; // Count of current blocked threads size_t wait_count; // Flag if the lock allows multiple acquisition bool multi_acquisition; // Flag if lock can be released by non owner bool strict_owner; // Current thread owning the lock struct $thread * owner; // Number of recursion level size_t recursion_count; }; struct mutex_lock { inline blocking_lock; }; struct owner_lock { inline blocking_lock; }; struct recursive_mutex_lock { inline blocking_lock; }; void ?{}( blocking_lock & this, bool multi_acquisition, bool strict_owner ); void ^?{}( blocking_lock & this ); void ?{}( mutex_lock & this ); void ^?{}( mutex_lock & this ); void ?{}( owner_lock & this ); void ^?{}( owner_lock & this ); void ?{}( recursive_mutex_lock & this ); void ^?{}( recursive_mutex_lock & this ); void lock( blocking_lock & this ); bool try_lock( blocking_lock & this ); void unlock( blocking_lock & this ); void add_( blocking_lock & this, struct $thread * t ); void remove_( blocking_lock & this ); size_t wait_count( blocking_lock & this ); void set_recursion_count( blocking_lock & this, size_t recursion ); size_t get_recursion_count( blocking_lock & this ); void lock( mutex_lock & this ); void unlock( mutex_lock & this ); void add_( mutex_lock & this, struct $thread * t ); void remove_( mutex_lock & this ); void set_recursion_count( mutex_lock & this, size_t recursion ); size_t get_recursion_count( mutex_lock & this ); void lock( recursive_mutex_lock & this ); void unlock( recursive_mutex_lock & this ); void add_( recursive_mutex_lock & this, struct $thread * t ); void remove_( recursive_mutex_lock & this ); void set_recursion_count( recursive_mutex_lock & this, size_t recursion ); size_t get_recursion_count( recursive_mutex_lock & this ); /////////////////////////////////////////////////////////////////// //// Synchronization Locks /////////////////////////////////////////////////////////////////// forall(dtype L | is_blocking_lock(L)) { struct synchronization_lock { // Spin lock used for mutual exclusion __spinlock_t lock; // List of blocked threads __queue_t( info_thread(L) ) blocked_threads; // Count of current blocked threads int count; // If true threads will reacquire the lock they block on upon waking bool reacquire_after_signal; }; struct condition_variable { inline synchronization_lock(L); }; struct thread_queue { inline synchronization_lock(L); }; void ?{}( synchronization_lock(L) & this, bool multi_acquisition, bool strict_owner ); void ^?{}( synchronization_lock(L) & this ); void ?{}( condition_variable(L) & this ); void ^?{}( condition_variable(L) & this ); void ?{}( thread_queue(L) & this ); void ^?{}( thread_queue(L) & this ); bool notify_one( synchronization_lock(L) & this ); bool notify_all( synchronization_lock(L) & this ); uintptr_t front( synchronization_lock(L) & this ); bool empty( synchronization_lock(L) & this ); int counter( synchronization_lock(L) & this ); // wait functions that are not passed a mutex lock void wait( synchronization_lock(L) & this ); void wait( synchronization_lock(L) & this, uintptr_t info ); bool wait( synchronization_lock(L) & this, Duration duration ); bool wait( synchronization_lock(L) & this, uintptr_t info, Duration duration ); bool wait( synchronization_lock(L) & this, Time time ); bool wait( synchronization_lock(L) & this, uintptr_t info, Time time ); // wait functions that are passed a lock bool notify_one( synchronization_lock(L) & this, L & l ); bool notify_all( synchronization_lock(L) & this, L & l ); void wait( synchronization_lock(L) & this, L & l ); void wait( synchronization_lock(L) & this, L & l, uintptr_t info ); bool wait( synchronization_lock(L) & this, L & l, Duration duration ); bool wait( synchronization_lock(L) & this, L & l, uintptr_t info, Duration duration ); bool wait( synchronization_lock(L) & this, L & l, Time time ); bool wait( synchronization_lock(L) & this, L & l, uintptr_t info, Time time ); } /////////////////////////////////////////////////////////////////// //// condition lock alternative approach /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// //// is_simple_lock /////////////////////////////////////////////////////////////////// trait is_simple_lock(dtype L | sized(L)) { void lock( L & ); // For synchronization locks to use when acquiring void unlock( L & ); // For synchronization locks to use when releasing size_t get_recursion_count( L & ); // to get recursion count for cond lock to reset after waking void set_recursion_count( L &, size_t recursion ); // to set recursion count after getting signalled; }; forall(dtype L | is_simple_lock(L)) { struct condition_lock { // Spin lock used for mutual exclusion mutex_lock m_lock; condition_variable( mutex_lock ) c_var; }; void ?{}( condition_lock(L) & this ); void ^?{}( condition_lock(L) & this ); bool notify_one( condition_lock(L) & this ); bool notify_all( condition_lock(L) & this ); void wait( condition_lock(L) & this, L & l ); }