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

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr no_list persistent-indexer pthread-emulation qualifiedEnum
Last change on this file since def9d4e was 3aeee3c, checked in by Thierry Delisle <tdelisle@…>, 7 years ago

Removed unnecessary alignment on locks

  • Property mode set to 100644
File size: 3.7 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 -- Fast internal locks.
8//
9// Author : Thierry Delisle
10// Created On : Tue Oct 31 15:14:38 2017
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Sat Aug 11 15:42:24 2018
13// Update Count : 10
14//
15
16#pragma once
17
18#include "bits/debug.hfa"
19#include "bits/defs.hfa"
20#include <assert.h>
21
22#ifdef __cforall
23 extern "C" {
24 #include <pthread.h>
25 }
26#endif
27
28// pause to prevent excess processor bus usage
29#if defined( __sparc )
30 #define Pause() __asm__ __volatile__ ( "rd %ccr,%g0" )
31#elif defined( __i386 ) || defined( __x86_64 )
32 #define Pause() __asm__ __volatile__ ( "pause" : : : )
33#elif defined( __ARM_ARCH )
34 #define Pause() __asm__ __volatile__ ( "nop" : : : )
35#else
36 #error unsupported architecture
37#endif
38
39struct __spinlock_t {
40 // Wrap in struct to prevent false sharing with debug info
41 volatile bool lock;
42 #ifdef __CFA_DEBUG__
43 // previous function to acquire the lock
44 const char * prev_name;
45 // previous thread to acquire the lock
46 void* prev_thrd;
47 #endif
48};
49
50#ifdef __cforall
51 extern "C" {
52 extern void disable_interrupts();
53 extern void enable_interrupts_noPoll();
54
55 #ifdef __CFA_DEBUG__
56 void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name);
57 #else
58 #define __cfaabi_dbg_record(x, y)
59 #endif
60 }
61
62 extern void yield( unsigned int );
63
64 static inline void ?{}( __spinlock_t & this ) {
65 this.lock = 0;
66 }
67
68 // Lock the spinlock, return false if already acquired
69 static inline bool try_lock ( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) {
70 bool result = (this.lock == 0) && (__atomic_test_and_set( &this.lock, __ATOMIC_ACQUIRE ) == 0);
71 if( result ) {
72 disable_interrupts();
73 __cfaabi_dbg_record( this, caller );
74 }
75 return result;
76 }
77
78 // Lock the spinlock, spin if already acquired
79 static inline void lock( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) {
80 #ifndef NOEXPBACK
81 enum { SPIN_START = 4, SPIN_END = 64 * 1024, };
82 unsigned int spin = SPIN_START;
83 #endif
84
85 for ( unsigned int i = 1;; i += 1 ) {
86 if ( (this.lock == 0) && (__atomic_test_and_set( &this.lock, __ATOMIC_ACQUIRE ) == 0) ) break;
87 #ifndef NOEXPBACK
88 // exponential spin
89 for ( volatile unsigned int s = 0; s < spin; s += 1 ) Pause();
90
91 // slowly increase by powers of 2
92 if ( i % 64 == 0 ) spin += spin;
93
94 // prevent overflow
95 if ( spin > SPIN_END ) spin = SPIN_START;
96 #else
97 Pause();
98 #endif
99 }
100 disable_interrupts();
101 __cfaabi_dbg_record( this, caller );
102 }
103
104 static inline void unlock( __spinlock_t & this ) {
105 enable_interrupts_noPoll();
106 __atomic_clear( &this.lock, __ATOMIC_RELEASE );
107 }
108
109
110 #ifdef __CFA_WITH_VERIFY__
111 extern bool __cfaabi_dbg_in_kernel();
112 #endif
113
114 struct __bin_sem_t {
115 bool signaled;
116 pthread_mutex_t lock;
117 pthread_cond_t cond;
118 };
119
120 static inline void ?{}(__bin_sem_t & this) with( this ) {
121 signaled = false;
122 pthread_mutex_init(&lock, NULL);
123 pthread_cond_init (&cond, NULL);
124 }
125
126 static inline void ^?{}(__bin_sem_t & this) with( this ) {
127 pthread_mutex_destroy(&lock);
128 pthread_cond_destroy (&cond);
129 }
130
131 static inline void wait(__bin_sem_t & this) with( this ) {
132 verify(__cfaabi_dbg_in_kernel());
133 pthread_mutex_lock(&lock);
134 if(!signaled) { // this must be a loop, not if!
135 pthread_cond_wait(&cond, &lock);
136 }
137 signaled = false;
138 pthread_mutex_unlock(&lock);
139 }
140
141 static inline void post(__bin_sem_t & this) with( this ) {
142 verify(__cfaabi_dbg_in_kernel());
143
144 pthread_mutex_lock(&lock);
145 bool needs_signal = !signaled;
146 signaled = true;
147 pthread_mutex_unlock(&lock);
148
149 if (needs_signal)
150 pthread_cond_signal(&cond);
151 }
152#endif
Note: See TracBrowser for help on using the repository browser.