// // Cforall Version 1.0.0 Copyright (C) 2021 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // locks.hfa -- PUBLIC // Runtime locks that used with the runtime thread system. // // Author : Colby Alexander Parsons // Created On : Thu Jan 21 19:46:50 2021 // Last Modified By : // Last Modified On : // Update Count : // #pragma once #include #include "bits/weakso_locks.hfa" #include "time_t.hfa" #include "time.hfa" //---------- struct single_acquisition_lock { inline blocking_lock; }; static inline void ?{}( single_acquisition_lock & this ) {((blocking_lock &)this){ false, false };} static inline void ^?{}( single_acquisition_lock & this ) {} static inline void lock ( single_acquisition_lock & this ) { lock ( (blocking_lock &)this ); } static inline void unlock ( single_acquisition_lock & this ) { unlock ( (blocking_lock &)this ); } static inline void on_wait ( single_acquisition_lock & this ) { on_wait( (blocking_lock &)this ); } static inline void on_notify ( single_acquisition_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); } static inline void set_recursion_count( single_acquisition_lock & this, size_t recursion ) { set_recursion_count( (blocking_lock &)this, recursion ); } static inline size_t get_recursion_count( single_acquisition_lock & this ) { return get_recursion_count( (blocking_lock &)this ); } //---------- struct owner_lock { inline blocking_lock; }; static inline void ?{}( owner_lock & this ) {((blocking_lock &)this){ true, true };} static inline void ^?{}( owner_lock & this ) {} static inline void lock ( owner_lock & this ) { lock ( (blocking_lock &)this ); } static inline void unlock ( owner_lock & this ) { unlock ( (blocking_lock &)this ); } static inline void on_wait ( owner_lock & this ) { on_wait( (blocking_lock &)this ); } static inline void on_notify( owner_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); } static inline void set_recursion_count( owner_lock & this, size_t recursion ) { set_recursion_count( (blocking_lock &)this, recursion ); } static inline size_t get_recursion_count( owner_lock & this ) { return get_recursion_count( (blocking_lock &)this ); } //----------------------------------------------------------------------------- // is_blocking_lock trait is_blocking_lock(L & | sized(L)) { // For synchronization locks to use when acquiring void on_notify( L &, struct $thread * ); // For synchronization locks to use when releasing void on_wait( L & ); // to get recursion count for cond lock to reset after waking size_t get_recursion_count( L & ); // to set recursion count after getting signalled; void set_recursion_count( L &, size_t recursion ); }; //----------------------------------------------------------------------------- // info_thread // the info thread is a wrapper around a thread used // to store extra data for use in the condition variable forall(L & | is_blocking_lock(L)) { struct info_thread; // for use by sequence info_thread(L) *& Back( info_thread(L) * this ); info_thread(L) *& Next( info_thread(L) * this ); } //----------------------------------------------------------------------------- // Synchronization Locks forall(L & | is_blocking_lock(L)) { struct condition_variable { // Spin lock used for mutual exclusion __spinlock_t lock; // List of blocked threads Sequence( info_thread(L) ) blocked_threads; // Count of current blocked threads int count; }; void ?{}( condition_variable(L) & this ); void ^?{}( condition_variable(L) & this ); bool notify_one( condition_variable(L) & this ); bool notify_all( condition_variable(L) & this ); uintptr_t front( condition_variable(L) & this ); bool empty ( condition_variable(L) & this ); int counter( condition_variable(L) & this ); void wait( condition_variable(L) & this ); void wait( condition_variable(L) & this, uintptr_t info ); bool wait( condition_variable(L) & this, Duration duration ); bool wait( condition_variable(L) & this, uintptr_t info, Duration duration ); bool wait( condition_variable(L) & this, Time time ); bool wait( condition_variable(L) & this, uintptr_t info, Time time ); void wait( condition_variable(L) & this, L & l ); void wait( condition_variable(L) & this, L & l, uintptr_t info ); bool wait( condition_variable(L) & this, L & l, Duration duration ); bool wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration ); bool wait( condition_variable(L) & this, L & l, Time time ); bool wait( condition_variable(L) & this, L & l, uintptr_t info, Time time ); } //----------------------------------------------------------------------------- // Semaphore struct semaphore { __spinlock_t lock; int count; __queue_t($thread) waiting; }; void ?{}(semaphore & this, int count = 1); void ^?{}(semaphore & this); bool P (semaphore & this); bool V (semaphore & this); bool V (semaphore & this, unsigned count);