Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release the TLS lock during allocations #53996

Closed
kristjanvalur mannequin opened this issue Sep 7, 2010 · 14 comments
Closed

Release the TLS lock during allocations #53996

kristjanvalur mannequin opened this issue Sep 7, 2010 · 14 comments
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error

Comments

@kristjanvalur
Copy link
Mannequin

kristjanvalur mannequin commented Sep 7, 2010

BPO 9787
Nosy @loewis, @pitrou, @kristjanvalur
Files
  • tlspatch.patch
  • tlspatch.patch
  • tlspatch.patch
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2012-03-31.11:38:29.305>
    created_at = <Date 2010-09-07.06:03:04.432>
    labels = ['interpreter-core', 'type-bug']
    title = 'Release the TLS lock during allocations'
    updated_at = <Date 2012-03-31.11:38:29.292>
    user = 'https://github.com/kristjanvalur'

    bugs.python.org fields:

    activity = <Date 2012-03-31.11:38:29.292>
    actor = 'kristjan.jonsson'
    assignee = 'none'
    closed = True
    closed_date = <Date 2012-03-31.11:38:29.305>
    closer = 'kristjan.jonsson'
    components = ['Interpreter Core']
    creation = <Date 2010-09-07.06:03:04.432>
    creator = 'kristjan.jonsson'
    dependencies = []
    files = ['18782', '18793', '24959']
    hgrepos = []
    issue_num = 9787
    keywords = ['patch']
    message_count = 14.0
    messages = ['115743', '115763', '115848', '116181', '116273', '116274', '116282', '116287', '116289', '156390', '156409', '156411', '156483', '157173']
    nosy_count = 3.0
    nosy_names = ['loewis', 'pitrou', 'kristjan.jonsson']
    pr_nums = []
    priority = 'low'
    resolution = 'wont fix'
    stage = None
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue9787'
    versions = ['Python 3.3']

    @kristjanvalur
    Copy link
    Mannequin Author

    kristjanvalur mannequin commented Sep 7, 2010

    Holding the "keymutex" lock during malloc and free operations is not a good idea. The reason is, that custom implementations of malloc and free, can use the TLS themselves. This is, for example, true in embedded situations, where one wants to replace malloc with, e.g. appMalloc, (to monitor the memory useage of Python) and appMalloc itself uses python TLS to find the current python State.

    This change makes the malloc and free calls outside the lock. The change in PyThread_set_key_value, requiring an extra lock allocate, has no significant performance impact since this is a rare api.

    @kristjanvalur kristjanvalur mannequin added interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error labels Sep 7, 2010
    @pitrou
    Copy link
    Member

    pitrou commented Sep 7, 2010

    You have a bug in PyThread_delete_key_value() (to_free = NULL?).
    Also, you should move the "/* NB This does *not* free p->value! */" comments at the right places.

    @kristjanvalur
    Copy link
    Mannequin Author

    kristjanvalur mannequin commented Sep 8, 2010

    You're right.
    Added a new version of the patch.

    @loewis
    Copy link
    Mannequin

    loewis mannequin commented Sep 12, 2010

    What is appMalloc, and what does it have to do with some Python lock?

    You seem to suggest that some malloc implementations make use of Python interpreter internals. I would call that a bug in the malloc implementation (it violates standard layering assumptions), and so I'm -1 on inclusion of this patch.

    @kristjanvalur
    Copy link
    Mannequin Author

    kristjanvalur mannequin commented Sep 13, 2010

    You may find this hard to believe, but we do in fact embed python into other applications. In this case, it is UnrealEngine, to drive a complex, console based game. Yes, embedding python is much harder than it need be and I'll submit some patches to make that easier someday, but that's not the point of this.

    appMalloc, is in this case, the canonical memory allocator in UnrealEngine. But it could be any other memory allocator so that is beside the point.

    The problem at hand, however, is this memory allocator _may_ have to inquire about the state of Python. It would do this, for example, to gather statistics about Python's memory use. This is critically important when developing console based applications, where every Kilobyte counts. Embedding python sometimes requires the replacement of the standard libc malloc with something else.

    What appMalloc is doing, in this case, is for every allocation, to get the python TLS pointer. There is nothing wrong with this, this is a GIL free operation, and it will return either NULL or the current TLS. And it works, except, when appMalloc (through python's malloc) is being invoked from the TLS entry creation mechanism itself. Then it deadlocks.

    Now, regardless of the above, surely it is an improvement in general if we make tighter use of the TLS lock. It's not a good idea to hold this lock across malloc calls if we can avoid it. The patch is harmless, might even be an improvement, so why object to it? It removes yet another "gotcha" that embedders, or those replacing malloc, (or instrumenting python's malloc use) have to face.

    Cheers,

    K

    @kristjanvalur
    Copy link
    Mannequin Author

    kristjanvalur mannequin commented Sep 13, 2010

    I forgot to add:  The API that our (instrumented) malloc implementation is calling is:
    PyGILState_GetThisThreadState();

    @loewis
    Copy link
    Mannequin

    loewis mannequin commented Sep 13, 2010

    You may find this hard to believe, but we do in fact embed python
    into other applications.

    This is actually very easy to believe.

    appMalloc, is in this case, the canonical memory allocator in
    UnrealEngine. But it could be any other memory allocator so that is
    beside the point.

    This seems to be the core of the issue. Any other memory allocator
    would *not* inquire about the state of Python. Any other memory
    allocator would not even be aware that it is used by Python.

    What appMalloc is doing, in this case, is for every allocation, to
    get the python TLS pointer. There is nothing wrong with this

    I find this wrong. It violates the software layering. The memory
    management layer is not supposed to access upper layers (such as
    the interpreter state, or the application state).

    Now, regardless of the above, surely it is an improvement in general
    if we make tighter use of the TLS lock. It's not a good idea to hold
    this lock across malloc calls if we can avoid it. The patch is
    harmless, might even be an improvement, so why object to it?

    The code change itself is harmless, yes. The comment is not. It imposes
    a requirement on Python (namely, that the malloc implementation may
    be free to make calls to Python) which is harmful. The malloc
    implementation just has no business looking at the thread state.

    So I remain -1 on this change.

    @kristjanvalur
    Copy link
    Mannequin Author

    kristjanvalur mannequin commented Sep 13, 2010

    The malloc
    implementation just has no business looking at the thread state.

    Of course it does, if it you want to have any hope of instrumenting your python memory usage with detailed python runtime information.

    Your statement islike saying: "A profiler has no business looking at the thread callstack."

    Note that we are not making any new requirements on python here. Merely facilitating the process, for those implementations that _wish_ to do so (at their own risk.)

    So, although you have nothing against the patch as such, you are against it on the principle that I am using it to facilitate something that you disapprove of. I find that a quite unreasonable position.

    @loewis
    Copy link
    Mannequin

    loewis mannequin commented Sep 13, 2010

    Note that we are not making any new requirements on python here.

    But you are. So far, there was no guarantee whatsoever about the state
    of Python when malloc is called. You are now introducing a requirement
    that Python must be in a certain state to make it correct to call
    malloc. IOW, this innocent change actually introduces a new feature.

    So, although you have nothing against the patch as such

    I think it's harmless - I don't think it is a good patch.
    It shouldn't matter whether or not it is applied (i.e. there is no
    change to Python that I can see).

    you are against it on the principle that I am using it to
    facilitate something that you disapprove of.
    I find that a quite unreasonable position.

    No. It's not the usage that I disapprove but, but the new requirement
    on Python. If you were able to do your profiling in a manner compatible
    with (the current) Python, it would be certainly fine with me.

    @kristjanvalur
    Copy link
    Mannequin Author

    kristjanvalur mannequin commented Mar 20, 2012

    I'll rework this for python 3.x and see where that gets us.

    @kristjanvalur
    Copy link
    Mannequin Author

    kristjanvalur mannequin commented Mar 20, 2012

    New patch, based on the cpython tip.

    @kristjanvalur
    Copy link
    Mannequin Author

    kristjanvalur mannequin commented Mar 20, 2012

    hm, for some reason this patch isn't viewable in side-by-side

    @kristjanvalur
    Copy link
    Mannequin Author

    kristjanvalur mannequin commented Mar 21, 2012

    Making this low priority since it applies only to platforms without Windows and pthread support.

    @kristjanvalur
    Copy link
    Mannequin Author

    kristjanvalur mannequin commented Mar 31, 2012

    Closing this since it applies only to our custom tls implementation. Most platforms use native tls now.

    @kristjanvalur kristjanvalur mannequin closed this as completed Mar 31, 2012
    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    1 participant