Commit 3ab99c52 authored by Xavier Thompson's avatar Xavier Thompson

Change cypclass 'Object Invocation Lock' implementation

parent 7ec14202
...@@ -676,7 +676,7 @@ def inject_cypclass_refcount_macros(): ...@@ -676,7 +676,7 @@ def inject_cypclass_refcount_macros():
def inject_cypclass_lock_macros(): def inject_cypclass_lock_macros():
blocking_macro_type = PyrexTypes.CFuncType(PyrexTypes.c_void_type, [PyrexTypes.CFuncTypeArg("obj", PyrexTypes.cy_object_type, None)], nogil = 1) blocking_macro_type = PyrexTypes.CFuncType(PyrexTypes.c_void_type, [PyrexTypes.CFuncTypeArg("obj", PyrexTypes.cy_object_type, None)], nogil = 1)
for macro in ("Cy_RLOCK", "Cy_WLOCK", "Cy_UNLOCK"): for macro in ("Cy_RLOCK", "Cy_WLOCK", "Cy_UNWLOCK", "Cy_UNRLOCK"):
builtin_scope.declare_builtin_cfunction(macro, blocking_macro_type, macro) builtin_scope.declare_builtin_cfunction(macro, blocking_macro_type, macro)
nonblocking_macro_type = PyrexTypes.CFuncType(PyrexTypes.c_int_type, [PyrexTypes.CFuncTypeArg("obj", PyrexTypes.cy_object_type, None)], nogil = 1) nonblocking_macro_type = PyrexTypes.CFuncType(PyrexTypes.c_int_type, [PyrexTypes.CFuncTypeArg("obj", PyrexTypes.cy_object_type, None)], nogil = 1)
for macro in ("Cy_TRYRLOCK", "Cy_TRYWLOCK"): for macro in ("Cy_TRYRLOCK", "Cy_TRYWLOCK"):
......
...@@ -465,11 +465,6 @@ class CypclassLockTransform(Visitor.EnvTransform): ...@@ -465,11 +465,6 @@ class CypclassLockTransform(Visitor.EnvTransform):
self.transform.rlocked[entry] += 1 self.transform.rlocked[entry] += 1
elif state == 'wlocked': elif state == 'wlocked':
self.transform.wlocked[entry] += 1 self.transform.wlocked[entry] += 1
elif state == 'unlocked':
if self.rlocked > 0:
self.transform.rlocked[entry] -= 1
elif self.wlocked > 0:
self.transform.wlocked[entry] -= 1
def __exit__(self, *args): def __exit__(self, *args):
entry = self.entry entry = self.entry
......
...@@ -14007,7 +14007,10 @@ class CoerceToLockedTempNode(CoerceToTempNode): ...@@ -14007,7 +14007,10 @@ class CoerceToLockedTempNode(CoerceToTempNode):
code.putln("Cy_WLOCK(%s);" % self.result()) code.putln("Cy_WLOCK(%s);" % self.result())
def generate_disposal_code(self, code): def generate_disposal_code(self, code):
code.putln("Cy_UNLOCK(%s);" % self.result()) if self.rlock_only:
code.putln("Cy_UNRLOCK(%s);" % self.result())
else:
code.putln("Cy_UNWLOCK(%s);" % self.result())
super(CoerceToLockedTempNode, self).generate_disposal_code(code) super(CoerceToLockedTempNode, self).generate_disposal_code(code)
......
...@@ -926,7 +926,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -926,7 +926,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_cyp_class_deferred_definitions(self, env, code, definition): def generate_cyp_class_deferred_definitions(self, env, code, definition):
""" """
Generate all cypclass method definitions, deferred till now Generate all cypclass method definitions, deferred till now.
""" """
for entry, scope in env.iter_cypclass_entries_and_scopes(): for entry, scope in env.iter_cypclass_entries_and_scopes():
...@@ -948,7 +948,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -948,7 +948,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_cyp_class_attrs_destructor_definition(self, entry, code): def generate_cyp_class_attrs_destructor_definition(self, entry, code):
""" """
Generate destructor definition for the given cypclass entry Generate destructor definition for the given cypclass entry.
""" """
scope = entry.type.scope scope = entry.type.scope
...@@ -966,7 +966,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -966,7 +966,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_cyp_class_activate_function(self, entry, code): def generate_cyp_class_activate_function(self, entry, code):
""" """
Generate activate function for activable cypclass entries Generate activate function for activable cypclass entries.
""" """
active_self_entry = entry.type.scope.lookup_here("<active_self>") active_self_entry = entry.type.scope.lookup_here("<active_self>")
...@@ -1016,7 +1016,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1016,7 +1016,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_cyp_class_activated_class(self, entry, code): def generate_cyp_class_activated_class(self, entry, code):
""" """
Generate activated class Generate activated cypclass.
""" """
from . import Builtin from . import Builtin
...@@ -1085,7 +1085,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1085,7 +1085,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("if (this->%s != NULL) {" % queue_attr_cname) code.putln("if (this->%s != NULL) {" % queue_attr_cname)
code.putln("Cy_WLOCK(%s);" % queue_attr_cname) code.putln("Cy_WLOCK(%s);" % queue_attr_cname)
code.putln("this->%s->push(message);" % queue_attr_cname) code.putln("this->%s->push(message);" % queue_attr_cname)
code.putln("Cy_UNLOCK(%s);" % queue_attr_cname) code.putln("Cy_UNWLOCK(%s);" % queue_attr_cname)
code.putln("} else {") code.putln("} else {")
code.putln("/* We should definitely shout here */") code.putln("/* We should definitely shout here */")
code.putln('fprintf(stderr, "Acthon error: No queue to push to for %s remote call !\\n");' % reified_function_entry.name) code.putln('fprintf(stderr, "Acthon error: No queue to push to for %s remote call !\\n");' % reified_function_entry.name)
...@@ -1098,7 +1098,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1098,7 +1098,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_cyp_class_reifying_entries(self, entry, code): def generate_cyp_class_reifying_entries(self, entry, code):
""" """
Generate code to reify the cypclass entry ? -> TODO what does this do exactly ? Generate code to reify the cypclass entries.
""" """
target_object_type = entry.type target_object_type = entry.type
...@@ -1217,7 +1217,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1217,7 +1217,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("if (this->%s != NULL) {" % sync_attr_cname) code.putln("if (this->%s != NULL) {" % sync_attr_cname)
code.putln("if (!Cy_TRYRLOCK(this->%s)) {" % sync_attr_cname) code.putln("if (!Cy_TRYRLOCK(this->%s)) {" % sync_attr_cname)
code.putln("%s = this->%s->isActivable();" % (sync_result, sync_attr_cname)) code.putln("%s = this->%s->isActivable();" % (sync_result, sync_attr_cname))
code.putln("Cy_UNLOCK(this->%s);" % sync_attr_cname) code.putln("Cy_UNRLOCK(this->%s);" % sync_attr_cname)
code.putln("}") code.putln("}")
code.putln("if (%s == 0) return 0;" % sync_result) code.putln("if (%s == 0) return 0;" % sync_result)
code.putln("}") code.putln("}")
...@@ -1297,19 +1297,22 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1297,19 +1297,22 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
num_unlock = 0 num_unlock = 0
# Target object first, then arguments # Target object first, then arguments
code.putln("if (%s > %s) {" % (trylock_result, num_unlock)) code.putln("if (%s > %s) {" % (trylock_result, num_unlock))
code.putln("Cy_UNLOCK(this->%s);" % target_object_cname) unlock_op = "Cy_UNRLOCK" if reified_function_entry.type.is_const_method else "Cy_UNWLOCK"
code.putln("%s(this->%s);" % (unlock_op, target_object_cname))
num_unlock += 1 num_unlock += 1
for i, narg in enumerate(func_type.args[:narg_count]): for i, narg in enumerate(func_type.args[:narg_count]):
if narg.type.is_cyp_class: if narg.type.is_cyp_class:
code.putln("if (%s > %s) {" % (trylock_result, num_unlock)) code.putln("if (%s > %s) {" % (trylock_result, num_unlock))
code.putln("Cy_UNLOCK(this->%s);" % narg.cname) unlock_op = "Cy_UNRLOCK" if narg.type.is_const else "Cy_UNWLOCK"
code.putln("%s(this->%s);" % (unlock_op, narg.cname))
num_unlock += 1 num_unlock += 1
if opt_arg_count and num_optional_if: if opt_arg_count and num_optional_if:
code.putln("if (this->%s != NULL) {" % opt_arg_name) code.putln("if (this->%s != NULL) {" % opt_arg_name)
for opt_idx, optarg in enumerate(func_type.args[narg_count:]): for opt_idx, optarg in enumerate(func_type.args[narg_count:]):
if optarg.type.is_cyp_class: if optarg.type.is_cyp_class:
code.putln("if (%s > %s) {" % (trylock_result, num_unlock)) code.putln("if (%s > %s) {" % (trylock_result, num_unlock))
code.putln("Cy_UNLOCK(this->%s->%s);" % (opt_arg_name, func_type.opt_arg_cname(optarg.name))) unlock_op = "Cy_UNRLOCK" if optarg.type.is_const else "Cy_UNWLOCK"
code.putln("%s(this->%s->%s);" % (unlock_op, opt_arg_name, func_type.opt_arg_cname(optarg.name)))
num_unlock += 1 num_unlock += 1
# Note: we do not respect the semantic order of end-blocks here for simplification purpose. # Note: we do not respect the semantic order of end-blocks here for simplification purpose.
# This one is for the "not NULL opt arg" check # This one is for the "not NULL opt arg" check
...@@ -1330,8 +1333,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1330,8 +1333,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
", ".join("this->%s" % arg_cname for arg_cname in reified_call_args_list) ", ".join("this->%s" % arg_cname for arg_cname in reified_call_args_list)
) )
) )
code.putln("Cy_UNLOCK(this->%s);" % target_object_cname) unlock_op = "Cy_UNRLOCK" if reified_function_entry.type.is_const_method else "Cy_UNWLOCK"
put_cypclass_op_on_narg_optarg(lambda _: "Cy_UNLOCK", reified_function_entry.type, Naming.optional_args_cname, code) code.putln("%s(this->%s);" % (unlock_op, target_object_cname))
arg_unlocker = lambda arg: "Cy_UNRLOCK" if arg.type.is_const else "Cy_UNWLOCK"
put_cypclass_op_on_narg_optarg(arg_unlocker, reified_function_entry.type, Naming.optional_args_cname, code)
code.putln("/* Push result in the result object */") code.putln("/* Push result in the result object */")
if does_return: if does_return:
code.putln("Cy_WLOCK(this->%s);" % result_attr_cname) code.putln("Cy_WLOCK(this->%s);" % result_attr_cname)
...@@ -1339,7 +1344,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1339,7 +1344,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("this->%s->pushIntResult(result);" % result_attr_cname) code.putln("this->%s->pushIntResult(result);" % result_attr_cname)
else: else:
code.putln("this->%s->pushVoidStarResult((void*)result);" % result_attr_cname) code.putln("this->%s->pushVoidStarResult((void*)result);" % result_attr_cname)
code.putln("Cy_UNLOCK(this->%s);" % result_attr_cname) code.putln("Cy_UNWLOCK(this->%s);" % result_attr_cname)
code.putln("return 1;") code.putln("return 1;")
code.putln("}") code.putln("}")
...@@ -1354,7 +1359,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1354,7 +1359,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_cyp_class_wrapper_definition(self, type, wrapper_entry, constructor_entry, new_entry, alloc_entry, code): def generate_cyp_class_wrapper_definition(self, type, wrapper_entry, constructor_entry, new_entry, alloc_entry, code):
""" """
Generate cypclass constructor wrapper ? -> TODO what does this do exactly ? Generate the cypclass constructor wrapper.
""" """
if type.templates: if type.templates:
......
...@@ -8546,7 +8546,7 @@ class EnsureGILNode(GILExitNode): ...@@ -8546,7 +8546,7 @@ class EnsureGILNode(GILExitNode):
code.put_ensure_gil(declare_gilstate=False) code.put_ensure_gil(declare_gilstate=False)
class LockCypclassNode(StatNode): class LockCypclassNode(StatNode):
# 'with rlocked / wlocked [cypclass object]' or 'with unlocked [cypclass object]' statement # 'with rlocked / wlocked [cypclass object]
# #
# state string 'rlocked' or 'wlocked' or 'unlocked' # state string 'rlocked' or 'wlocked' or 'unlocked'
# obj ExprNode the (un)locked object # obj ExprNode the (un)locked object
...@@ -8574,13 +8574,10 @@ class LockCypclassNode(StatNode): ...@@ -8574,13 +8574,10 @@ class LockCypclassNode(StatNode):
self.body.generate_execution_code(code) self.body.generate_execution_code(code)
# We must unlock if we held a lock previously, and relock if we unlocked. if self.state == "rlocked":
if self.state != "unlocked": code.putln("Cy_UNRLOCK(%s);" % self.obj.result())
code.putln("Cy_UNLOCK(%s);" % self.obj.result()) elif self.state == "wlocked":
elif self.was_wlocked: code.putln("Cy_UNWLOCK(%s);" % self.obj.result())
code.putln("Cy_WLOCK(%s);" % self.obj.result())
elif self.was_rlocked:
code.putln("Cy_RLOCK(%s);" % self.obj.result())
def cython_view_utility_code(): def cython_view_utility_code():
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment