From patchwork Mon Mar 2 14:34:14 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Petri Savolainen X-Patchwork-Id: 45289 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wg0-f70.google.com (mail-wg0-f70.google.com [74.125.82.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id C23362149C for ; Mon, 2 Mar 2015 14:35:08 +0000 (UTC) Received: by wghl18 with SMTP id l18sf23899032wgh.3 for ; Mon, 02 Mar 2015 06:35:07 -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=aUOEdKAPmfU69TBT+N0JkqJCx3P3Q/ocGay7VEERjyA=; b=URAnVLuRp8gekbCN9kpjmhmk1iqIYZYua4A5pOJp6sW1uh2OwqxGiQ0SY64vDgISL7 umsTPkGsRrUd8Q/lXHyn2U7UYWq2/I0dsYVWlT9Yg+ZgVACW//aAkQrK2eUc66E75eE5 uC8bGTajZnWbmQ0l79dFGFqjuy7IOGk+ZAx05tILgud0dtR0miAI5BCoFdSxpiYxLrMQ yhWJoA9Gllf6fi4kzywEceYrclJlcUswBLHONLKAnR+bdhWQz48S9Bakl+w5CXBWLsaz cSsCzRJVj6Ly6D3M27MEj8GcSGdETgjWpin9sLH7ktDPCzckqhY08RDZCNfktKLjkB+s JUzA== X-Gm-Message-State: ALoCoQmAPKYau9CeflFSWgghvMSYD/BAw5YY0/JhYmBiSm3f0wJom351yEENR2EDM/f/nEHUy5xW X-Received: by 10.194.239.41 with SMTP id vp9mr3841826wjc.5.1425306907937; Mon, 02 Mar 2015 06:35:07 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.197.97 with SMTP id it1ls326939lac.1.gmail; Mon, 02 Mar 2015 06:35:07 -0800 (PST) X-Received: by 10.152.5.194 with SMTP id u2mr5570158lau.88.1425306907771; Mon, 02 Mar 2015 06:35:07 -0800 (PST) Received: from mail-la0-f44.google.com (mail-la0-f44.google.com. [209.85.215.44]) by mx.google.com with ESMTPS id pw1si8974458lbb.72.2015.03.02.06.35.07 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 02 Mar 2015 06:35:07 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.44 as permitted sender) client-ip=209.85.215.44; Received: by labgd6 with SMTP id gd6so30686561lab.7 for ; Mon, 02 Mar 2015 06:35:07 -0800 (PST) X-Received: by 10.152.197.34 with SMTP id ir2mr24453805lac.36.1425306907539; Mon, 02 Mar 2015 06:35:07 -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 h5csp5563503lbj; Mon, 2 Mar 2015 06:35:06 -0800 (PST) X-Received: by 10.140.96.165 with SMTP id k34mr27816561qge.79.1425306904157; Mon, 02 Mar 2015 06:35:04 -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 f142si11752975qhc.75.2015.03.02.06.35.02 (version=TLSv1 cipher=RC4-SHA bits=128/128); Mon, 02 Mar 2015 06:35:04 -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 1YSRQy-0007b3-9l; Mon, 02 Mar 2015 14:35:00 +0000 Received: from mail-qc0-f169.google.com ([209.85.216.169]) by ip-10-35-177-41.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1YSRQs-0007aw-Gu for lng-odp@lists.linaro.org; Mon, 02 Mar 2015 14:34:54 +0000 Received: by qcvp6 with SMTP id p6so24725442qcv.9 for ; Mon, 02 Mar 2015 06:34:49 -0800 (PST) X-Received: by 10.140.89.146 with SMTP id v18mr48867335qgd.65.1425306889339; Mon, 02 Mar 2015 06:34:49 -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 o1sm660987qko.47.2015.03.02.06.34.46 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 02 Mar 2015 06:34:48 -0800 (PST) From: Petri Savolainen To: lng-odp@lists.linaro.org Date: Mon, 2 Mar 2015 16:34:14 +0200 Message-Id: <1425306854-10900-1-git-send-email-petri.savolainen@linaro.org> X-Mailer: git-send-email 2.3.1 X-Topics: patch Subject: [lng-odp] [PATCH] 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.215.44 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. Signed-off-by: Petri Savolainen --- platform/linux-generic/odp_thread.c | 115 +++++++++++++++++++++++++----------- 1 file changed, 81 insertions(+), 34 deletions(-) diff --git a/platform/linux-generic/odp_thread.c b/platform/linux-generic/odp_thread.c index c6813f5..bfdaaa2 100644 --- a/platform/linux-generic/odp_thread.c +++ b/platform/linux-generic/odp_thread.c @@ -1,3 +1,8 @@ + + + + + /* Copyright (c) 2013, Linaro Limited * All rights reserved. * @@ -11,7 +16,7 @@ #include #include -#include +#include #include #include #include @@ -22,19 +27,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 +65,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 +80,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 +147,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 +156,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)