source: libcfa/src/bits/locks.hfa @ ced5e2a

ADTast-experimentalpthread-emulationqualifiedEnum
Last change on this file since ced5e2a was ced5e2a, checked in by caparsons <caparson@…>, 2 years ago

removed debug fields from spinlock_t

  • Property mode set to 100644
File size: 2.3 KB
RevLine 
[ea7d2b0]1//
2// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
[454f478]7// bits/locks.hfa -- Basic spinlocks that are reused in the system.
8// Used for locks that aren't specific to cforall threads and can be used anywhere
9//
10//  *** Must not contain code specific to libcfathread ***
[ea7d2b0]11//
12// Author           : Thierry Delisle
13// Created On       : Tue Oct 31 15:14:38 2017
[b158d8f]14// Last Modified By : Peter A. Buhr
[fd9b524]15// Last Modified On : Wed Aug 12 14:18:07 2020
16// Update Count     : 13
[ea7d2b0]17//
18
19#pragma once
20
[73abe95]21#include "bits/debug.hfa"
22#include "bits/defs.hfa"
[ea8b2f7]23#include <assert.h>
24
[ea7d2b0]25struct __spinlock_t {
[13073be]26        // Wrap in struct to prevent false sharing with debug info
[3aeee3c]27        volatile bool lock;
28};
[ea7d2b0]29
[0cf5b79]30#ifdef __cforall
[dbe9b08]31        extern "C" {
[2026bb6]32                extern void disable_interrupts() OPTIONAL_THREAD;
[a3821fa]33                extern void enable_interrupts( bool poll = true ) OPTIONAL_THREAD;
[ced5e2a]34                #define __cfaabi_dbg_record_lock(x, y)
[dbe9b08]35        }
36
[ea7d2b0]37        static inline void ?{}( __spinlock_t & this ) {
38                this.lock = 0;
39        }
40
41        // Lock the spinlock, return false if already acquired
[93c2e0a]42        static inline bool try_lock  ( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) {
[3381ed7]43                disable_interrupts();
[93c2e0a]44                bool result = (this.lock == 0) && (__atomic_test_and_set( &this.lock, __ATOMIC_ACQUIRE ) == 0);
[dbe9b08]45                if( result ) {
[ae66348]46                        __cfaabi_dbg_record_lock( this, caller );
[3381ed7]47                } else {
[a3821fa]48                        enable_interrupts( false );
[dbe9b08]49                }
[ea7d2b0]50                return result;
51        }
52
53        // Lock the spinlock, spin if already acquired
[36982fc]54        static inline void lock( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) {
[ea7d2b0]55                #ifndef NOEXPBACK
56                        enum { SPIN_START = 4, SPIN_END = 64 * 1024, };
57                        unsigned int spin = SPIN_START;
58                #endif
59
[3381ed7]60                disable_interrupts();
[ea7d2b0]61                for ( unsigned int i = 1;; i += 1 ) {
[13073be]62                        if ( (this.lock == 0) && (__atomic_test_and_set( &this.lock, __ATOMIC_ACQUIRE ) == 0) ) break;
[ea7d2b0]63                        #ifndef NOEXPBACK
64                                // exponential spin
65                                for ( volatile unsigned int s = 0; s < spin; s += 1 ) Pause();
66
67                                // slowly increase by powers of 2
68                                if ( i % 64 == 0 ) spin += spin;
69
70                                // prevent overflow
71                                if ( spin > SPIN_END ) spin = SPIN_START;
72                        #else
73                                Pause();
74                        #endif
75                }
[ae66348]76                __cfaabi_dbg_record_lock( this, caller );
[ea7d2b0]77        }
78
79        static inline void unlock( __spinlock_t & this ) {
[13073be]80                __atomic_clear( &this.lock, __ATOMIC_RELEASE );
[a3821fa]81                enable_interrupts( false );
[ea7d2b0]82        }
[b158d8f]83#endif
Note: See TracBrowser for help on using the repository browser.