From patchwork Mon Mar 2 14:45:00 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Petri Savolainen X-Patchwork-Id: 45290 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f69.google.com (mail-la0-f69.google.com [209.85.215.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 1B44B2149C for ; Mon, 2 Mar 2015 14:46:17 +0000 (UTC) Received: by labge10 with SMTP id ge10sf24336831lab.3 for ; Mon, 02 Mar 2015 06:46:16 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:subject :precedence:list-id:list-unsubscribe:list-archive:list-post :list-help:list-subscribe:mime-version:content-type :content-transfer-encoding:errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list; bh=gap5B4NP1Zb92dyeJRcaQJCvf3T3o2S6s5KjBLMUovc=; b=PxSOBGBZlZ0bs1n4ovGSqbKgLkjtqulWH1sw+O7P9/NVF9KMrvPMg8Bxa2DVLDT4CA snP3eg1cjxC0sUqLGcaauUFnQrWW0nlfT69OVS9TPGCM+sIjxM48UN0fSwN1cAzbzgwR tcy+h/EFWsBXzZw+Av3h8hq33AufH/stf9z17s+rEBIkj1T4ucWrQek2atJVr9mfJmKz dlQTBCixKZ0jrdtRC6JPvyxXSFI7mVrZQnKqVSYlsze1JrJCVn+rROEZ4zEhtQgzTssW evhej6VCUlYmQ3ZXLOdIEeVFkWt3CfpO1lkVKpTFy/qRF0r4K7tb6jJcMK7t/g0M9qDT fgHA== X-Gm-Message-State: ALoCoQn1fHS0W/+RNqKRtwfen0wB98aS98CcZRjcPnT0v1UL2jO81GHzJlnEYeEBJO7idlw9nacr X-Received: by 10.112.144.130 with SMTP id sm2mr3928190lbb.9.1425307575998; Mon, 02 Mar 2015 06:46:15 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.87.48 with SMTP id u16ls85265laz.106.gmail; Mon, 02 Mar 2015 06:46:15 -0800 (PST) X-Received: by 10.112.12.228 with SMTP id b4mr24381733lbc.83.1425307575783; Mon, 02 Mar 2015 06:46:15 -0800 (PST) Received: from mail-lb0-f181.google.com (mail-lb0-f181.google.com. [209.85.217.181]) by mx.google.com with ESMTPS id nq11si8929195lbc.148.2015.03.02.06.46.15 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 02 Mar 2015 06:46:15 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.181 as permitted sender) client-ip=209.85.217.181; Received: by lbiw7 with SMTP id w7so30449802lbi.9 for ; Mon, 02 Mar 2015 06:46:15 -0800 (PST) X-Received: by 10.152.206.70 with SMTP id lm6mr24971585lac.35.1425307575645; Mon, 02 Mar 2015 06:46:15 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.35.133 with SMTP id h5csp5569683lbj; Mon, 2 Mar 2015 06:46:14 -0800 (PST) X-Received: by 10.55.18.14 with SMTP id c14mr6104684qkh.25.1425307573709; Mon, 02 Mar 2015 06:46:13 -0800 (PST) Received: from ip-10-35-177-41.ec2.internal (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTPS id z123si11768014qhd.91.2015.03.02.06.46.12 (version=TLSv1 cipher=RC4-SHA bits=128/128); Mon, 02 Mar 2015 06:46:13 -0800 (PST) Received-SPF: none (google.com: lng-odp-bounces@lists.linaro.org does not designate permitted sender hosts) client-ip=54.225.227.206; Received: from localhost ([127.0.0.1] helo=ip-10-35-177-41.ec2.internal) by ip-10-35-177-41.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1YSRbk-0008QC-As; Mon, 02 Mar 2015 14:46:08 +0000 Received: from mail-qc0-f181.google.com ([209.85.216.181]) by ip-10-35-177-41.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1YSRbe-0008Q1-Jz for lng-odp@lists.linaro.org; Mon, 02 Mar 2015 14:46:02 +0000 Received: by qcwb13 with SMTP id b13so24809162qcw.7 for ; Mon, 02 Mar 2015 06:45:57 -0800 (PST) X-Received: by 10.140.235.197 with SMTP id g188mr50769941qhc.86.1425307557395; Mon, 02 Mar 2015 06:45:57 -0800 (PST) Received: from mcpro03.emea.nsn-net.net (ec2-23-23-178-99.compute-1.amazonaws.com. [23.23.178.99]) by mx.google.com with ESMTPSA id w66sm8494815qha.25.2015.03.02.06.45.53 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 02 Mar 2015 06:45:56 -0800 (PST) From: Petri Savolainen To: lng-odp@lists.linaro.org Date: Mon, 2 Mar 2015 16:45:00 +0200 Message-Id: <1425307500-11450-1-git-send-email-petri.savolainen@linaro.org> X-Mailer: git-send-email 2.3.1 X-Topics: patch Subject: [lng-odp] [PATCH v2] linux-generic: thread: reuse thread ids X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Errors-To: lng-odp-bounces@lists.linaro.org Sender: lng-odp-bounces@lists.linaro.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: petri.savolainen@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.181 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 Scheduler validation test failed on a 28 thread machine since it creates and terminates many threads during a test run. Linux-generix implementation did not reuse thread IDs but run out of threads. Thread ids are protected with a lock and new alloc/free rutines reuse thread IDs. Fixes https://bugs.linaro.org/show_bug.cgi?id=1294 Signed-off-by: Petri Savolainen --- v2: Removed white space and added link to the bug --- platform/linux-generic/odp_thread.c | 110 +++++++++++++++++++++++++----------- 1 file changed, 76 insertions(+), 34 deletions(-) diff --git a/platform/linux-generic/odp_thread.c b/platform/linux-generic/odp_thread.c index c6813f5..e815009 100644 --- a/platform/linux-generic/odp_thread.c +++ b/platform/linux-generic/odp_thread.c @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include #include @@ -22,19 +22,19 @@ #include #include +#define MASK_SIZE_16 ((ODP_CONFIG_MAX_THREADS+15)/16) typedef struct { - int thr_id; + int thr; int cpu; - } thread_state_t; typedef struct { - thread_state_t thr[ODP_CONFIG_MAX_THREADS]; - odp_atomic_u32_t num; - odp_atomic_u32_t next_id; - + thread_state_t thr[ODP_CONFIG_MAX_THREADS]; + uint16_t mask[MASK_SIZE_16]; + uint32_t num; + odp_spinlock_t lock; } thread_globals_t; @@ -60,8 +60,7 @@ int odp_thread_init_global(void) return -1; memset(thread_globals, 0, sizeof(thread_globals_t)); - odp_atomic_init_u32(&thread_globals->next_id, 0); - odp_atomic_init_u32(&thread_globals->num, 0); + odp_spinlock_init(&thread_globals->lock); return 0; } @@ -76,19 +75,65 @@ int odp_thread_term_global(void) return ret; } +static int alloc_id(void) +{ + int i, j; + uint16_t *mask = thread_globals->mask; + + if (thread_globals->num >= ODP_CONFIG_MAX_THREADS) + return -1; + + for (i = 0; i < MASK_SIZE_16; i++) { + if (mask[i] != 0xffff) { + for (j = 0; j < 16; j++) { + uint16_t bit = 0x1 << j; + if ((bit & mask[i]) == 0) { + mask[i] |= bit; + thread_globals->num++; + return i*16 + j; + } + } + return -2; + } + } + + return -2; +} + +static int free_id(int id) +{ + int i, j; + uint16_t *mask = thread_globals->mask; + uint16_t bit; + + if (id < 0 || id >= ODP_CONFIG_MAX_THREADS) + return -1; + + i = id / 16; + j = id - (i * 16); + bit = 0x1 << j; + + if ((bit & mask[i]) == 0) + return -1; + + mask[i] &= ~bit; + thread_globals->num--; + return thread_globals->num; +} -static int thread_id(void) +int odp_thread_init_local(void) { - uint32_t id; + int id; int cpu; - id = odp_atomic_fetch_inc_u32(&thread_globals->next_id); + odp_spinlock_lock(&thread_globals->lock); + id = alloc_id(); + odp_spinlock_unlock(&thread_globals->lock); - if (id >= ODP_CONFIG_MAX_THREADS) { + if (id < 0) { ODP_ERR("Too many threads\n"); return -1; } - odp_atomic_inc_u32(&thread_globals->num); cpu = sched_getcpu(); @@ -97,20 +142,8 @@ static int thread_id(void) return -1; } - thread_globals->thr[id].thr_id = id; - thread_globals->thr[id].cpu = cpu; - - return id; -} - -int odp_thread_init_local(void) -{ - int id; - - id = thread_id(); - - if (id < 0) - return -1; + thread_globals->thr[id].thr = id; + thread_globals->thr[id].cpu = cpu; this_thread = &thread_globals->thr[id]; return 0; @@ -118,20 +151,29 @@ int odp_thread_init_local(void) int odp_thread_term_local(void) { - uint32_t num; - num = odp_atomic_fetch_dec_u32(&thread_globals->num); - ODP_ASSERT(num > 0, "Number of threads should be > 0"); - return num - 1; /* return a number of threads left */ + int num; + int id = this_thread->thr; + + odp_spinlock_lock(&thread_globals->lock); + num = free_id(id); + odp_spinlock_unlock(&thread_globals->lock); + + if (num < 0) { + ODP_ERR("failed to free thread id %i", id); + return -1; + } + + return num; /* return a number of threads left */ } int odp_thread_id(void) { - return this_thread->thr_id; + return this_thread->thr; } int odp_thread_count(void) { - return odp_atomic_load_u32(&thread_globals->num); + return thread_globals->num; } int odp_cpu_id(void)