40
40
*/
41
41
package com .oracle .graal .python .builtins .objects .thread ;
42
42
43
+ import static com .oracle .graal .python .builtins .objects .thread .AbstractPythonLock .DEFAULT_BLOCKING ;
44
+ import static com .oracle .graal .python .builtins .objects .thread .AbstractPythonLock .DEFAULT_TIMEOUT ;
45
+ import static com .oracle .graal .python .builtins .objects .thread .AbstractPythonLock .TIMEOUT_MAX ;
43
46
import static com .oracle .graal .python .nodes .SpecialMethodNames .__ENTER__ ;
44
47
import static com .oracle .graal .python .nodes .SpecialMethodNames .__EXIT__ ;
45
48
import static com .oracle .graal .python .nodes .SpecialMethodNames .__REPR__ ;
49
+ import static com .oracle .graal .python .runtime .exception .PythonErrorType .OverflowError ;
46
50
import static com .oracle .graal .python .runtime .exception .PythonErrorType .ValueError ;
47
51
48
52
import java .util .List ;
59
63
import com .oracle .graal .python .nodes .function .builtins .PythonTernaryBuiltinNode ;
60
64
import com .oracle .graal .python .nodes .function .builtins .PythonUnaryBuiltinNode ;
61
65
import com .oracle .graal .python .nodes .util .CastToDoubleNode ;
66
+ import com .oracle .truffle .api .CompilerDirectives ;
67
+ import com .oracle .truffle .api .CompilerDirectives .CompilationFinal ;
62
68
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
63
69
import com .oracle .truffle .api .dsl .Cached ;
64
70
import com .oracle .truffle .api .dsl .GenerateNodeFactory ;
65
71
import com .oracle .truffle .api .dsl .NodeFactory ;
66
72
import com .oracle .truffle .api .dsl .Specialization ;
73
+ import com .oracle .truffle .api .profiles .ConditionProfile ;
67
74
68
75
@ CoreFunctions (extendClasses = PythonBuiltinClassType .PLock )
69
76
public class LockBuiltins extends PythonBuiltins {
@@ -75,68 +82,80 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
75
82
@ Builtin (name = "acquire" , minNumOfPositionalArgs = 1 , maxNumOfPositionalArgs = 3 , keywordArguments = {"blocking" , "timeout" })
76
83
@ GenerateNodeFactory
77
84
abstract static class AcquireLockNode extends PythonTernaryBuiltinNode {
78
- @ Specialization
79
- @ TruffleBoundary
80
- boolean doAcquire (PLock self , @ SuppressWarnings ("unused" ) PNone waitFlag , @ SuppressWarnings ("unused" ) PNone timeout ) {
81
- return self .acquire (true );
82
- }
85
+ private @ Child CastToDoubleNode castToDoubleNode ;
86
+ private @ Child CastToBooleanNode castToBooleanNode ;
87
+ private @ CompilationFinal ConditionProfile isBlockingProfile = ConditionProfile .createBinaryProfile ();
88
+ private @ CompilationFinal ConditionProfile defaultTimeoutProfile = ConditionProfile .createBinaryProfile ();
83
89
84
- @ Specialization
85
- @ TruffleBoundary
86
- boolean doAcquire (PLock self , Object blocking , @ SuppressWarnings ("unused" ) PNone timeout ,
87
- @ Cached ("createIfTrueNode()" ) CastToBooleanNode castToBooleanNode ) {
88
- return self .acquire (castToBooleanNode .executeWith (blocking ));
90
+ private CastToDoubleNode getCastToDoubleNode () {
91
+ if (castToDoubleNode == null ) {
92
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
93
+ castToDoubleNode = insert (CastToDoubleNode .create ());
94
+ }
95
+ return castToDoubleNode ;
89
96
}
90
97
91
- @ Specialization
92
- @ TruffleBoundary
93
- boolean doAcquire (PLock self , @ SuppressWarnings ("unused" ) PNone waitFlag , Object timeout ,
94
- @ Cached ("create()" ) CastToDoubleNode castToDoubleNode ) {
95
- double timeoutSeconds = castToDoubleNode .execute (timeout );
96
- if (timeoutSeconds < 0 ) {
97
- throw raise (ValueError , "timeout value must be positive" );
98
+ private CastToBooleanNode getCastToBooleanNode () {
99
+ if (castToBooleanNode == null ) {
100
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
101
+ castToBooleanNode = insert (CastToBooleanNode .createIfTrueNode ());
98
102
}
99
- return self . acquire ( true , timeoutSeconds ) ;
103
+ return castToBooleanNode ;
100
104
}
101
105
102
106
@ Specialization
103
- @ TruffleBoundary
104
- boolean doAcquire (PLock self , Object blocking , Object timeout ,
105
- @ Cached ("create()" ) CastToDoubleNode castToDoubleNode ,
106
- @ Cached ("createIfTrueNode()" ) CastToBooleanNode castToBooleanNode ) {
107
- boolean isBlocking = castToBooleanNode .executeWith (blocking );
108
- if (!isBlocking ) {
109
- throw raise (ValueError , "can't specify a timeout for a non-blocking call" );
107
+ boolean doAcquire (PLock self , Object blocking , Object timeout ) {
108
+ // args setup
109
+ boolean isBlocking = (blocking instanceof PNone ) ? DEFAULT_BLOCKING : getCastToBooleanNode ().executeWith (blocking );
110
+ double timeoutSeconds = DEFAULT_TIMEOUT ;
111
+ if (!(timeout instanceof PNone )) {
112
+ if (!isBlocking ) {
113
+ throw raise (ValueError , "can't specify a timeout for a non-blocking call" );
114
+ }
115
+
116
+ timeoutSeconds = getCastToDoubleNode ().execute (timeout );
117
+
118
+ if (timeoutSeconds < 0 ) {
119
+ throw raise (ValueError , "timeout value must be positive" );
120
+ } else if (timeoutSeconds > TIMEOUT_MAX ) {
121
+ throw raise (OverflowError , "timeout value is too large" );
122
+ }
110
123
}
111
- double timeoutSeconds = castToDoubleNode .execute (timeout );
112
- if (timeoutSeconds < 0 ) {
113
- throw raise (ValueError , "timeout value must be positive" );
124
+
125
+ // acquire lock
126
+ if (isBlockingProfile .profile (!isBlocking )) {
127
+ return self .acquireNonBlocking ();
128
+ } else {
129
+ if (defaultTimeoutProfile .profile (timeoutSeconds == DEFAULT_TIMEOUT )) {
130
+ return self .acquireBlocking ();
131
+ } else {
132
+ return self .acquireTimeout (timeoutSeconds );
133
+ }
114
134
}
115
- return self .acquire (true , timeoutSeconds );
116
135
}
117
136
118
137
public static AcquireLockNode create () {
119
138
return AcquireLockNodeFactory .create ();
120
139
}
121
140
}
122
141
123
- @ Builtin (name = "acquire_lock" , minNumOfPositionalArgs = 1 , maxNumOfPositionalArgs = 3 , keywordArguments = {"waitflag " , "timeout" })
142
+ @ Builtin (name = "acquire_lock" , minNumOfPositionalArgs = 1 , maxNumOfPositionalArgs = 3 , keywordArguments = {"blocking " , "timeout" })
124
143
@ GenerateNodeFactory
125
144
abstract static class AcquireLockLockNode extends PythonTernaryBuiltinNode {
126
145
@ Specialization
127
- Object acquire (PLock self , Object waitFlag , Object timeout ,
146
+ Object acquire (PLock self , Object blocking , Object timeout ,
128
147
@ Cached ("create()" ) AcquireLockNode acquireLockNode ) {
129
- return acquireLockNode .execute (self , waitFlag , timeout );
148
+ return acquireLockNode .execute (self , blocking , timeout );
130
149
}
131
150
}
132
151
133
- @ Builtin (name = __ENTER__ , minNumOfPositionalArgs = 1 , maxNumOfPositionalArgs = 3 , keywordArguments = {"waitflag " , "timeout" })
152
+ @ Builtin (name = __ENTER__ , minNumOfPositionalArgs = 1 , maxNumOfPositionalArgs = 3 , keywordArguments = {"blocking " , "timeout" })
134
153
@ GenerateNodeFactory
135
154
abstract static class EnterLockNode extends PythonTernaryBuiltinNode {
136
155
@ Specialization
137
- Object acquire (PLock self , Object waitFlag , Object timeout ,
156
+ Object acquire (PLock self , Object blocking , Object timeout ,
138
157
@ Cached ("create()" ) AcquireLockNode acquireLockNode ) {
139
- return acquireLockNode .execute (self , waitFlag , timeout );
158
+ return acquireLockNode .execute (self , blocking , timeout );
140
159
}
141
160
}
142
161
0 commit comments