source: libcfa/src/bits/locks.hfa@ 9e27f69

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 9e27f69 was 454f478, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

Re-arranged and commented low-level headers.
Main goal was for better support of weakso locks that are comming.

  • Property mode set to 100644
File size: 2.5 KB
Line 
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//
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 ***
11//
12// Author : Thierry Delisle
13// Created On : Tue Oct 31 15:14:38 2017
14// Last Modified By : Peter A. Buhr
15// Last Modified On : Wed Aug 12 14:18:07 2020
16// Update Count : 13
17//
18
19#pragma once
20
21#include "bits/debug.hfa"
22#include "bits/defs.hfa"
23#include <assert.h>
24
25struct __spinlock_t {
26 // Wrap in struct to prevent false sharing with debug info
27 volatile bool lock;
28 #ifdef __CFA_DEBUG__
29 // previous function to acquire the lock
30 const char * prev_name;
31 // previous thread to acquire the lock
32 void* prev_thrd;
33 #endif
34};
35
36#ifdef __cforall
37 extern "C" {
38 extern void disable_interrupts() OPTIONAL_THREAD;
39 extern void enable_interrupts_noPoll() OPTIONAL_THREAD;
40
41 #ifdef __CFA_DEBUG__
42 void __cfaabi_dbg_record_lock(__spinlock_t & this, const char prev_name[]);
43 #else
44 #define __cfaabi_dbg_record_lock(x, y)
45 #endif
46 }
47
48 static inline void ?{}( __spinlock_t & this ) {
49 this.lock = 0;
50 }
51
52 // Lock the spinlock, return false if already acquired
53 static inline bool try_lock ( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) {
54 disable_interrupts();
55 bool result = (this.lock == 0) && (__atomic_test_and_set( &this.lock, __ATOMIC_ACQUIRE ) == 0);
56 if( result ) {
57 __cfaabi_dbg_record_lock( this, caller );
58 } else {
59 enable_interrupts_noPoll();
60 }
61 return result;
62 }
63
64 // Lock the spinlock, spin if already acquired
65 static inline void lock( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) {
66 #ifndef NOEXPBACK
67 enum { SPIN_START = 4, SPIN_END = 64 * 1024, };
68 unsigned int spin = SPIN_START;
69 #endif
70
71 disable_interrupts();
72 for ( unsigned int i = 1;; i += 1 ) {
73 if ( (this.lock == 0) && (__atomic_test_and_set( &this.lock, __ATOMIC_ACQUIRE ) == 0) ) break;
74 #ifndef NOEXPBACK
75 // exponential spin
76 for ( volatile unsigned int s = 0; s < spin; s += 1 ) Pause();
77
78 // slowly increase by powers of 2
79 if ( i % 64 == 0 ) spin += spin;
80
81 // prevent overflow
82 if ( spin > SPIN_END ) spin = SPIN_START;
83 #else
84 Pause();
85 #endif
86 }
87 __cfaabi_dbg_record_lock( this, caller );
88 }
89
90 static inline void unlock( __spinlock_t & this ) {
91 __atomic_clear( &this.lock, __ATOMIC_RELEASE );
92 enable_interrupts_noPoll();
93 }
94#endif
Note: See TracBrowser for help on using the repository browser.