From patchwork Tue Nov 6 21:38:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 150352 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp4419341ljp; Tue, 6 Nov 2018 13:57:32 -0800 (PST) X-Google-Smtp-Source: AJdET5dQLRUtzPaVL7NjqTQjQjuDrxLdQq78rByxtd8jPnq+fYFGEKYdZPdCrzrpUXCGELzGT6ws X-Received: by 2002:ac8:34cb:: with SMTP id x11mr26998301qtb.115.1541541452537; Tue, 06 Nov 2018 13:57:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1541541452; cv=none; d=google.com; s=arc-20160816; b=yLXsO57xgTPrzrxcWcYoCE96DV+YdIthQfxIy6dZkraubU1iVC1BtaX2nRLGHxvST/ 2z/ATFlr7QzMy+iqvdbAvy0YRFl+Wi0qVXfcOeR0N9aV5tstq6RLk4X5YyssALXWFWBK zCUx/rH7sJZxCnQKS4qHXJIrj27g3e/Ln3mRDgTADylDbMO/M2HUUPlfiV8YL5TBbaZl M+KbYFJfMY4iJyDazRpyEyl6xQ6mUT5+1GIldvWg7mol/YQ9FPQZhiouIVgJRBkD89jO cQNRbhXscUQ0qzzL4J464A8ovG0AQb6grKkjtLxdDVKTHuFlELMtC0cERkNjGO5NbFdZ rYSQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=7+axY70qcUOtqstSVvA5kHaZ7m2L8vni+JyNkUQ6rA0=; b=Hmnl5qjJeOO8AamehrBUab0TUgnrXxQHv9nPcCbtI3L9FEO/VGvlE7WDHC4ZQqn9VF TVBA67qVDY7ov8XTVS/MV9O0ZyAqmXa79AwSCBmSoA69f2hrYK2OyjDtxTvdQH7f/6Kw ReqnDr3WEXzEAOTi+AXkGns6r62YqMoJ8BNwnga41B030Em5jsZ6cqDS95G26jYFZGCa KsMqhdsX4soA1I+QbPfD9mAYB2R/sEEEM/xqXwQ/Gv4KqujhdTAEvLt+WRO+KbiGnpZF wbcKy3Jnf3J0j+PU4jV9An/eMz1ePhIi9A8GjGopF+PQEJfQrgLWmC5SgS37IGrz+oBP Sllw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=ngmzvmyW; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id t5si4919432qvj.105.2018.11.06.13.57.32 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Nov 2018 13:57:32 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=ngmzvmyW; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from localhost ([::1]:43959 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gK9Ln-0007bx-U8 for patch@linaro.org; Tue, 06 Nov 2018 16:57:31 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40434) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gK9Cq-0002qu-FI for qemu-devel@nongnu.org; Tue, 06 Nov 2018 16:48:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gK93X-0001S7-1E for qemu-devel@nongnu.org; Tue, 06 Nov 2018 16:38:43 -0500 Received: from mail-wm1-x336.google.com ([2a00:1450:4864:20::336]:55904) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gK93W-0000h8-41 for qemu-devel@nongnu.org; Tue, 06 Nov 2018 16:38:38 -0500 Received: by mail-wm1-x336.google.com with SMTP id s10-v6so12270266wmc.5 for ; Tue, 06 Nov 2018 13:38:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=7+axY70qcUOtqstSVvA5kHaZ7m2L8vni+JyNkUQ6rA0=; b=ngmzvmyWMLUKzM0bnKCFMNau+qIXxBx1spg+4qFIwxodqz9SXWCNY607eDorzjWHA7 i/Q0B0U52hYd5fzlxfwXKEEqkaTgW7p6ZbmAe9OeRxvD+T+hXQZR3mUdIt1we7zpIH6Y CYhwiHximIPSMr0+5avA/OjV/I4Yvvj2RVCp9Gw8+OrySPZO96v6PsI0RfM4XmABJNOs rj52mcA8M4xmSGBukuGtf/WVJMWVnSSrED9AoicrJ314Ul/mknFqXUFlobRbd1S8oE21 F4M2UwJ2Es0cGqttJbR+H8pbt7xp2mEXuPFbo5PfP6hgIOs3l6IBdKdA5vrpjS4uR/Ne Ndtw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=7+axY70qcUOtqstSVvA5kHaZ7m2L8vni+JyNkUQ6rA0=; b=aqwSZmO7It5h1z5bAojvVtybWTO1Gh6h4OeLJtJEFP6SJi6sC5Mkzpq4DwZLmCnVMD smlXSHP7UE8sqgzcsccKmxg9bTQNC3WSvLafZWoC/7mntI21EDM90wC3P5lzz5PykL8O HOkVQXw3yVPrnptrOWyB9mE+hJW5PdJvjL9Xaq6Rcy724oh3CZdbmsKNvVsO80Fw5aQD ieK9+qoo7iUAEAD8GhNGiXi23Tgi0o/kcuZlHWocVIiTlcfNB1VM2UFLdoVyNs0NpFW5 rAl9KuQ3mVgLdh4i7m3A7DD7h/qwTMagVjakNKHppagk0NexS6nV9f4PFwd7+GR+wsSw TB+Q== X-Gm-Message-State: AGRZ1gIodhY1JNiMq3lWiEziKFZKXOx4iwpneX1ojQ6wh5q4qI+N48iS oa9PM2ghTYSY+WhZKzYCoxZvVet9 X-Received: by 2002:a1c:9ed2:: with SMTP id h201-v6mr3358364wme.31.1541540305243; Tue, 06 Nov 2018 13:38:25 -0800 (PST) Received: from 640k.lan ([93.56.166.5]) by smtp.gmail.com with ESMTPSA id l186-v6sm3223526wma.13.2018.11.06.13.38.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Nov 2018 13:38:24 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Tue, 6 Nov 2018 22:38:03 +0100 Message-Id: <1541540283-45699-18-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1541540283-45699-1-git-send-email-pbonzini@redhat.com> References: <1541540283-45699-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::336 Subject: [Qemu-devel] [PULL 17/17] util/qemu-thread-posix: Fix qemu_thread_atexit* for OSX X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Peter Maydell Our current implementation of qemu_thread_atexit* is broken on OSX. This is because it works by cerating a piece of thread-specific data with pthread_key_create() and using the destructor function for that data to run the notifier function passed to it by the caller of qemu_thread_atexit_add(). The expected use case is that the caller uses a __thread variable as the notifier, and uses the callback to clean up information that it is keeping per-thread in __thread variables. Unfortunately, on OSX this does not work, because on OSX a __thread variable may be destroyed (freed) before the pthread_key_create() destructor runs. (POSIX imposes no ordering constraint here; the OSX implementation happens to implement __thread variables in terms of pthread_key_create((), whereas Linux uses different mechanisms that mean the __thread variables will still be present when the pthread_key_create() destructor is run.) Fix this by switching to a scheme similar to the one qemu-thread-win32 uses for qemu_thread_atexit: keep the thread's notifiers on a __thread variable, and run the notifiers on calls to qemu_thread_exit() and on return from the start routine passed to qemu_thread_start(). We do this with the pthread_cleanup_push() API. We take advantage of the qemu_thread_atexit_add() API permission not to run thread notifiers on process exit to avoid having to special case the main thread. Suggested-by: Paolo Bonzini Signed-off-by: Peter Maydell Reviewed-by: Eric Blake Message-Id: <20181105135538.28025-3-peter.maydell@linaro.org> Signed-off-by: Paolo Bonzini --- util/qemu-thread-posix.c | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) -- 1.8.3.1 diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index dfa66ff..865e476 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -443,42 +443,34 @@ void qemu_event_wait(QemuEvent *ev) } } -static pthread_key_t exit_key; - -union NotifierThreadData { - void *ptr; - NotifierList list; -}; -QEMU_BUILD_BUG_ON(sizeof(union NotifierThreadData) != sizeof(void *)); +static __thread NotifierList thread_exit; +/* + * Note that in this implementation you can register a thread-exit + * notifier for the main thread, but it will never be called. + * This is OK because main thread exit can only happen when the + * entire process is exiting, and the API allows notifiers to not + * be called on process exit. + */ void qemu_thread_atexit_add(Notifier *notifier) { - union NotifierThreadData ntd; - ntd.ptr = pthread_getspecific(exit_key); - notifier_list_add(&ntd.list, notifier); - pthread_setspecific(exit_key, ntd.ptr); + notifier_list_add(&thread_exit, notifier); } void qemu_thread_atexit_remove(Notifier *notifier) { - union NotifierThreadData ntd; - ntd.ptr = pthread_getspecific(exit_key); notifier_remove(notifier); - pthread_setspecific(exit_key, ntd.ptr); -} - -static void qemu_thread_atexit_run(void *arg) -{ - union NotifierThreadData ntd = { .ptr = arg }; - notifier_list_notify(&ntd.list, NULL); } -static void __attribute__((constructor)) qemu_thread_atexit_init(void) +static void qemu_thread_atexit_notify(void *arg) { - pthread_key_create(&exit_key, qemu_thread_atexit_run); + /* + * Called when non-main thread exits (via qemu_thread_exit() + * or by returning from its start routine.) + */ + notifier_list_notify(&thread_exit, NULL); } - typedef struct { void *(*start_routine)(void *); void *arg; @@ -490,6 +482,7 @@ static void *qemu_thread_start(void *args) QemuThreadArgs *qemu_thread_args = args; void *(*start_routine)(void *) = qemu_thread_args->start_routine; void *arg = qemu_thread_args->arg; + void *r; #ifdef CONFIG_PTHREAD_SETNAME_NP /* Attempt to set the threads name; note that this is for debug, so @@ -501,7 +494,10 @@ static void *qemu_thread_start(void *args) #endif g_free(qemu_thread_args->name); g_free(qemu_thread_args); - return start_routine(arg); + pthread_cleanup_push(qemu_thread_atexit_notify, NULL); + r = start_routine(arg); + pthread_cleanup_pop(1); + return r; } void qemu_thread_create(QemuThread *thread, const char *name,