From patchwork Tue Aug 1 10:00:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Github ODP bot X-Patchwork-Id: 109134 Delivered-To: patch@linaro.org Received: by 10.182.45.195 with SMTP id p3csp4750164obm; Tue, 1 Aug 2017 03:04:40 -0700 (PDT) X-Received: by 10.200.36.196 with SMTP id t4mr24524022qtt.227.1501581880260; Tue, 01 Aug 2017 03:04:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1501581880; cv=none; d=google.com; s=arc-20160816; b=haIDbSSef/G6jizFzxNmBY/9qhacpV8Seu4hP591oVYWnzMRWZ42sPq9TaAJNMyxZO 2tYBlwbpAtE/B5c0aZm4o7OPLPx5djRP6YujgmnmJPrXrMoNdWDOInHCF8i7WfCZBxjy 2PKMJKcYkT2a1CfxsB0TgssCZKiWjZ3UgnsegSuLAf3wMU9TBKlnyZ7P29UKm1zc1Q2V CJQXKPxutZnO+uiLOrfzXJnVy7yzJpzXPPpR9Jwk0yoAA8g/bIU3y/8O1b33h5G+cV5n y+SOCdKFll/zuuzoWxFTTIcFciUvnggJwc+cGP4r7AgSwvFJYkkbufclvraqw+QzSm31 TFWQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:github-pr-num :references:in-reply-to:message-id:date:to:from:delivered-to :arc-authentication-results; bh=10HpfFIS7oxUJjqXWaay15bgc/PUJmrrUiPy68Rmrnw=; b=uOCRLApBYUVIfUaVGrIbi0QSKnoGrzIZvA2tJCirdRFFbZJE0KLJnRP9WLkiPpoSDh 8HsuI89MsQsOUXdI1AxV9NNvy/8NS9Cl5Lto8BF//y+1FjCGZ4Xi/45KZgJniYsXJgxj yf1r2mDspzGG8GR3MHWvZ21TlTaCdNuWpIbU1sth/YFhWCZWx7xCTemAttV6V0nrX8Wp ZFkWs1RZNHMsg+vW9/Q+C0mS9Uc6Uk0kKQp4T/XikC/FpwWInLJIlyPBTppn4NfhzEjd 3ePZs9HDIeSMEBzFAnu9l6rlDUbs9UGeVJs9mW5nnTOfYVlE1cOEkMYrUKM7kBX0zZsG QEiQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id x10si7949391qta.192.2017.08.01.03.04.40; Tue, 01 Aug 2017 03:04:40 -0700 (PDT) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Received: by lists.linaro.org (Postfix, from userid 109) id EEBAE65D52; Tue, 1 Aug 2017 10:04:39 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_LOW,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 7B46265D54; Tue, 1 Aug 2017 10:01:43 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 6DFE765D02; Tue, 1 Aug 2017 10:01:36 +0000 (UTC) Received: from forward2o.cmail.yandex.net (forward2o.cmail.yandex.net [37.9.109.243]) by lists.linaro.org (Postfix) with ESMTPS id A2C276088F for ; Tue, 1 Aug 2017 10:01:31 +0000 (UTC) Received: from smtp4p.mail.yandex.net (smtp4p.mail.yandex.net [IPv6:2a02:6b8:0:1402::15:6]) by forward2o.cmail.yandex.net (Yandex) with ESMTP id 984172107E for ; Tue, 1 Aug 2017 13:01:30 +0300 (MSK) Received: from smtp4p.mail.yandex.net (localhost.localdomain [127.0.0.1]) by smtp4p.mail.yandex.net (Yandex) with ESMTP id A204B65013FC for ; Tue, 1 Aug 2017 13:00:21 +0300 (MSK) Received: by smtp4p.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id 9Zh4PEf7BG-0KlKLDat; Tue, 01 Aug 2017 13:00:20 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client certificate not present) X-Yandex-Suid-Status: 1 0 From: Github ODP bot To: lng-odp@lists.linaro.org Date: Tue, 1 Aug 2017 13:00:08 +0300 Message-Id: <1501581610-4854-2-git-send-email-odpbot@yandex.ru> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1501581610-4854-1-git-send-email-odpbot@yandex.ru> References: <1501581610-4854-1-git-send-email-odpbot@yandex.ru> Github-pr-num: 65 Subject: [lng-odp] [PATCH CLOUD-DEV v3 1/3] example: ddf_app: add .gitignore X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" From: Yi He Signed-off-by: Yi He --- /** Email created from pull request 65 (heyi-linaro:modular-framework) ** https://github.com/Linaro/odp/pull/65 ** Patch: https://github.com/Linaro/odp/pull/65.patch ** Base sha: 1ba26aa5650c05718c177842178de6d0f70b7fc1 ** Merge commit sha: 6ec2e428f70182f80be27e5d403b9359cae20500 **/ example/ddf_app/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 example/ddf_app/.gitignore diff --git a/example/ddf_app/.gitignore b/example/ddf_app/.gitignore new file mode 100644 index 00000000..f79a1409 --- /dev/null +++ b/example/ddf_app/.gitignore @@ -0,0 +1 @@ +odp_ddf_app From patchwork Tue Aug 1 10:00:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Github ODP bot X-Patchwork-Id: 109133 Delivered-To: patch@linaro.org Received: by 10.182.45.195 with SMTP id p3csp4749384obm; Tue, 1 Aug 2017 03:03:58 -0700 (PDT) X-Received: by 10.200.9.75 with SMTP id z11mr26083561qth.283.1501581838091; Tue, 01 Aug 2017 03:03:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1501581838; cv=none; d=google.com; s=arc-20160816; b=vRPXj6L689WYgmF/u8FPuhBPuJ4Fbk59KebgU4l3sj2dToILbwegHEgs5jeq1e+kWI yJ+MOUiLb5BqcOiIdZTefF+lStvScncq2VF8hdjmN7jvW/pndNl+2kcAL33mt6aorD7N N/sggccDfyHCbMWj8GL35i8nzhpN6NNn43nDwvVrhCw+MpvhGAjpDQ+aq17LyNQrbX6t 12mcXRNo0EY+x4pEmbOoDScR0SV2hOeMT/2OsCfVkBKqE7r1DDu+gdBIEKPv5ZnPU6iI Zv0wThXOk5+BMAwtLGU63Jl9aJ4BjChYPnPDzpVkn+biYmegMAj2W8jcjcrJzbFfUNVB 01QA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:github-pr-num :references:in-reply-to:message-id:date:to:from:delivered-to :arc-authentication-results; bh=hqhi1ce7wqIWanCWwh5hDx+wXdYkB82JjDJDon1q9OA=; b=baE/i0Z3o3Jh7OtSVvqvGYvq6+8KwpqkVGBJxxMBHYgzyIv0bqR2XUmp+gx9siLd0g wWfpphm+RBBOOTNfrAj2+pMQfEpzj+eiOnMGVpLDwxl0tAcGSLa0BbiU5EI1Otyd+oXr mBR1eUWEu84YET4sckCh3DjAAEeAZQVAUqr+Vw94DTTS7eIzRqReoo5b2YZ/Feyxrt26 PGnv+bsrq1ZkGecp3U6W/jCUxK77C7LC4yrpETo+e+MkCaQG+UpXhk0OxnLmCy2QKAy1 AZM2WsBCaz0PR+fnYWnDsxpZpyiZ4WreiIAdrsqzn63Ex+xhvXBPHFn+k6OyAaDtLQaK UNew== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id v24si236829qth.59.2017.08.01.03.03.57; Tue, 01 Aug 2017 03:03:58 -0700 (PDT) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Received: by lists.linaro.org (Postfix, from userid 109) id BD6CB6446D; Tue, 1 Aug 2017 10:03:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_LOW,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 160AA65D02; Tue, 1 Aug 2017 10:01:41 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id E522A636AA; Tue, 1 Aug 2017 10:01:32 +0000 (UTC) Received: from forward2o.cmail.yandex.net (forward2o.cmail.yandex.net [37.9.109.243]) by lists.linaro.org (Postfix) with ESMTPS id CA15460854 for ; Tue, 1 Aug 2017 10:01:30 +0000 (UTC) Received: from smtp4p.mail.yandex.net (smtp4p.mail.yandex.net [95.108.252.166]) by forward2o.cmail.yandex.net (Yandex) with ESMTP id C515B21072 for ; Tue, 1 Aug 2017 13:01:28 +0300 (MSK) Received: from smtp4p.mail.yandex.net (localhost.localdomain [127.0.0.1]) by smtp4p.mail.yandex.net (Yandex) with ESMTP id 315656501558 for ; Tue, 1 Aug 2017 13:00:23 +0300 (MSK) Received: by smtp4p.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id 9Zh4PEf7BG-0MliQb8B; Tue, 01 Aug 2017 13:00:22 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client certificate not present) X-Yandex-Suid-Status: 1 0 From: Github ODP bot To: lng-odp@lists.linaro.org Date: Tue, 1 Aug 2017 13:00:09 +0300 Message-Id: <1501581610-4854-3-git-send-email-odpbot@yandex.ru> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1501581610-4854-1-git-send-email-odpbot@yandex.ru> References: <1501581610-4854-1-git-send-email-odpbot@yandex.ru> Github-pr-num: 65 Subject: [lng-odp] [PATCH CLOUD-DEV v3 2/3] validation: pktio: disable socket mmsg pktio X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" From: Yi He It was not working already, the problem are obscured in make check because with static pktio_if_ops array socket mmap pktio always take precedence over socket mmsg pktio. Signed-off-by: Yi He --- /** Email created from pull request 65 (heyi-linaro:modular-framework) ** https://github.com/Linaro/odp/pull/65 ** Patch: https://github.com/Linaro/odp/pull/65.patch ** Base sha: 1ba26aa5650c05718c177842178de6d0f70b7fc1 ** Merge commit sha: 6ec2e428f70182f80be27e5d403b9359cae20500 **/ test/linux-generic/validation/api/pktio/pktio_env | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/linux-generic/validation/api/pktio/pktio_env b/test/linux-generic/validation/api/pktio/pktio_env index 345b5bd5..3a6f9e89 100644 --- a/test/linux-generic/validation/api/pktio/pktio_env +++ b/test/linux-generic/validation/api/pktio/pktio_env @@ -103,6 +103,9 @@ setup_pktio_env() return 5 fi done + + # disable socket mmsg pktio since it was not working already + export ODP_PKTIO_DISABLE_SOCKET_MMSG=1 } cleanup_pktio_env() From patchwork Tue Aug 1 10:00:10 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Github ODP bot X-Patchwork-Id: 109132 Delivered-To: patch@linaro.org Received: by 10.182.45.195 with SMTP id p3csp4746967obm; Tue, 1 Aug 2017 03:01:55 -0700 (PDT) X-Received: by 10.237.57.163 with SMTP id m32mr25684479qte.117.1501581715029; Tue, 01 Aug 2017 03:01:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1501581715; cv=none; d=google.com; s=arc-20160816; b=AjQyTQmGuhjDL+wbgd2nFC+agzyaJJO1wcBqFqfS/G0wNorlXLtSo3l8LoVmWhHgzb Lv9XrhWDgbJkIBd7lKVGqteo3FMQrBJqs4SgxUA0MPE+Ba/B2ujnlYrDzmmkdRo9u8/J LGc8z0Q/Wh5pQbdFwp9uhEy96wApooZbvSxOjM+PFv6MsvFLSD233B8+x5aoMcoe/KcX q1TOssilzN4Sq38mu75y5mU0sNrOUmB0HfiVjzDs0IbjnuzsN314K+xMiHQgNXPOWqXt RMFfRZ2CGtmIOuQmlGLrtqpmMkEXVcZ9Ky7pBP5MFLXiyLcwW+YjXvjdsl9tzYiUApYr 5MYg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:github-pr-num :references:in-reply-to:message-id:date:to:from:delivered-to :arc-authentication-results; bh=lvnyPsAmkKeLfY1vl1ldhFDOuLzY0U/tPmeTv7yEZNo=; b=Xn0gEW9+Jv9NDgLS9zyZGuRMhIw9c9BXP2xtPfh5UiCTtmJmYkpkVlAZIsLcgfxtpc fs9HioieAnLy2jQuYjlocDKF70j9KdjV7EKf2o35+HJsirjDVnd3rUTF3tD4k8lvBT46 vXMxzWV1ewP6bPVlx37B5CT08BK82sUQ6vQhKNlDCwiTItopuON99spXDde0VMqiqI3b EYXVUYFR+wddx/myLxvHuRV5XIpIGPRrYKfna/LyJA5tZchD+XBb+zbcgpuKGeVFpHgH wW58eR86iDhfRoSAS8TSpc6tkkI3NrmTe2GCZzlFvvkvPdv4D8e3Z/L1CId4OhrbvM9C RffQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id w34si7578837qtd.181.2017.08.01.03.01.54; Tue, 01 Aug 2017 03:01:55 -0700 (PDT) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Received: by lists.linaro.org (Postfix, from userid 109) id 7928965D60; Tue, 1 Aug 2017 10:01:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-0.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, URIBL_BLOCKED, URIBL_SBL, URIBL_SBL_A autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id A7F2960D76; Tue, 1 Aug 2017 10:01:35 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 6EE7C60D76; Tue, 1 Aug 2017 10:01:31 +0000 (UTC) Received: from forward1j.cmail.yandex.net (forward1j.cmail.yandex.net [5.255.227.19]) by lists.linaro.org (Postfix) with ESMTPS id 936CD636AA for ; Tue, 1 Aug 2017 10:01:24 +0000 (UTC) Received: from smtp4p.mail.yandex.net (smtp4p.mail.yandex.net [IPv6:2a02:6b8:0:1402::15:6]) by forward1j.cmail.yandex.net (Yandex) with ESMTP id 2C0AD20FC9 for ; Tue, 1 Aug 2017 13:01:23 +0300 (MSK) Received: from smtp4p.mail.yandex.net (localhost.localdomain [127.0.0.1]) by smtp4p.mail.yandex.net (Yandex) with ESMTP id 609A26501392 for ; Tue, 1 Aug 2017 13:00:25 +0300 (MSK) Received: by smtp4p.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id 9Zh4PEf7BG-0OlWHcSL; Tue, 01 Aug 2017 13:00:24 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client certificate not present) X-Yandex-Suid-Status: 1 0 From: Github ODP bot To: lng-odp@lists.linaro.org Date: Tue, 1 Aug 2017 13:00:10 +0300 Message-Id: <1501581610-4854-4-git-send-email-odpbot@yandex.ru> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1501581610-4854-1-git-send-email-odpbot@yandex.ru> References: <1501581610-4854-1-git-send-email-odpbot@yandex.ru> Github-pr-num: 65 Subject: [lng-odp] [PATCH CLOUD-DEV v3 3/3] odp: add modular framework X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" From: Yi He Add modular programming framework to support selectable implementations for variant software subsystems. Signed-off-by: Yi He --- /** Email created from pull request 65 (heyi-linaro:modular-framework) ** https://github.com/Linaro/odp/pull/65 ** Patch: https://github.com/Linaro/odp/pull/65.patch ** Base sha: 1ba26aa5650c05718c177842178de6d0f70b7fc1 ** Merge commit sha: 6ec2e428f70182f80be27e5d403b9359cae20500 **/ frameworks/modular/list.h | 264 ++++++++++++++++++ frameworks/modular/module.c | 164 ++++++++++++ frameworks/modular/module.h | 296 +++++++++++++++++++++ include/odp/api/spec/atomic.h | 5 + include/odp/api/spec/rwlock.h | 4 + platform/linux-generic/Makefile.am | 8 + .../include/odp/api/plat/atomic_types.h | 2 + .../include/odp/api/plat/rwlock_types.h | 2 + 8 files changed, 745 insertions(+) create mode 100644 frameworks/modular/list.h create mode 100644 frameworks/modular/module.c create mode 100644 frameworks/modular/module.h diff --git a/frameworks/modular/list.h b/frameworks/modular/list.h new file mode 100644 index 00000000..40f6b2a6 --- /dev/null +++ b/frameworks/modular/list.h @@ -0,0 +1,264 @@ +/* Adopted and modified Rusty Russell CCAN Project + * https://github.com/rustyrussell/ccan + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef CCAN_LIST_H +#define CCAN_LIST_H + +#include +#include + +/* Always assume the availabilities of typeof or __typeof__ */ +#if defined(__STDC__) +#define typeof __typeof__ +#endif + +/** + * struct list_node - an entry in a doubly-linked list + * @next: next entry (self if empty) + * @prev: previous entry (self if empty) + * + * This is used as an entry in a linked list. + * Example: + * struct child { + * const char *name; + * // Linked list of all us children. + * struct list_node list; + * }; + */ +struct list_node { + struct list_node *next, *prev; +}; + +/** + * struct list_head - the head of a doubly-linked list + * @node: the head node + * + * This is used as the head of a linked list. + * Example: + * struct parent { + * const char *name; + * struct list_head children; + * unsigned int num_children; + * }; + */ +struct list_head { + struct list_node node; +}; + +/** + * LIST_HEAD_INIT - initializer for an empty list_head + * @name: the name of the list. + * + * Explicit initializer for an empty list. + * + * See also: + * LIST_HEAD, list_head_init() + * + * Example: + * static struct list_head my_list = LIST_HEAD_INIT(my_list); + */ +#define LIST_HEAD_INIT(name) { { &(name).node, &(name).node } } + +/** + * list_head_init - initialize a list_head + * @h: the list_head to set to the empty list + * + * Example: + * ... + * struct parent *parent = malloc(sizeof(*parent)); + * + * list_head_init(&parent->children); + * parent->num_children = 0; + */ +static inline void list_head_init(struct list_head *h) +{ + h->node.next = &h->node; + h->node.prev = &h->node; +} + +/** + * list_node_init - initialize a list_node + * @n: the list_node to link to itself. + * + * You don't need to use this normally! But it lets you list_del(@n) + * safely. + */ +static inline void list_node_init(struct list_node *n) +{ + n->next = n; + n->prev = n; +} + +/** + * list_add_after - add an entry after an existing node in a linked list + * @p: the existing list_node to add the node after + * @n: the new list_node to add to the list. + * + * The existing list_node must already be a member of the list. + * The new list_node does not need to be initialized; it will be overwritten. + * + * Example: + * struct child c1, c2, c3; + * LIST_HEAD(h); + * + * list_add_tail(&h, &c1.list); + * list_add_tail(&h, &c3.list); + * list_add_after(&c1.list, &c2.list); + */ +static inline void list_add_after(struct list_node *p, + struct list_node *n) +{ + n->next = p->next; + n->prev = p; + p->next->prev = n; + p->next = n; +} + +/** + * list_add - add an entry at the start of a linked list. + * @h: the list_head to add the node to + * @n: the list_node to add to the list. + * + * The list_node does not need to be initialized; it will be overwritten. + * Example: + * struct child *child = malloc(sizeof(*child)); + * + * child->name = "marvin"; + * list_add(&parent->children, &child->list); + * parent->num_children++; + */ +static inline void list_add(struct list_head *h, + struct list_node *n) +{ + list_add_after(&h->node, n); +} + +/** + * list_add_before - add an entry before an existing node in a linked list + * @p: the existing list_node to add the node before + * @n: the new list_node to add to the list. + * + * The existing list_node must already be a member of the list. + * The new list_node does not need to be initialized; it will be overwritten. + * + * Example: + * list_head_init(&h); + * list_add_tail(&h, &c1.list); + * list_add_tail(&h, &c3.list); + * list_add_before(&c3.list, &c2.list); + */ +static inline void list_add_before(struct list_node *p, + struct list_node *n) +{ + n->next = p; + n->prev = p->prev; + p->prev->next = n; + p->prev = n; +} + +/** + * list_add_tail - add an entry at the end of a linked list. + * @h: the list_head to add the node to + * @n: the list_node to add to the list. + * + * The list_node does not need to be initialized; it will be overwritten. + * Example: + * list_add_tail(&parent->children, &child->list); + * parent->num_children++; + */ +static inline void list_add_tail(struct list_head *h, + struct list_node *n) +{ + list_add_before(&h->node, n); +} + +/** + * list_empty - is a list empty? + * @h: the list_head + * + * If the list is empty, returns true. + * + * Example: + * assert(list_empty(&parent->children) == (parent->num_children == 0)); + */ +static inline bool list_empty(const struct list_head *h) +{ + return (h->node.next == &h->node); +} + +/** + * list_node_detached - is a node detached from any lists? + * @n: the list_node + * + * If the list node is initialized and detached, return true. + * Always use list_node_init() and list_del_init() on list nodes. + */ +static inline bool list_node_detached(const struct list_node *n) +{ + return (n->next == n); +} + +/** + * list_del - delete an entry from an (unknown) linked list. + * @n: the list_node to delete from the list. + * + * Note that this leaves @n in an undefined state; it can be added to + * another list, but not deleted again. + * + * See also: + * list_del_from(), list_del_init() + * + * Example: + * list_del(&child->list); + * parent->num_children--; + */ +static inline void list_del(struct list_node *n) +{ + n->next->prev = n->prev; + n->prev->next = n->next; + + /* Catch use-after-del. */ + n->next = NULL; + n->prev = NULL; +} + +/** + * list_del_init - delete a node, and reset it so it can be deleted again. + * @n: the list_node to be deleted. + * + * list_del(@n) or list_del_init() again after this will be safe, + * which can be useful in some cases. + * + * See also: + * list_del_from(), list_del() + * + * Example: + * list_del_init(&child->list); + * parent->num_children--; + */ +static inline void list_del_init(struct list_node *n) +{ + list_del(n); + list_node_init(n); +} + +#endif /* CCAN_LIST_H */ diff --git a/frameworks/modular/module.c b/frameworks/modular/module.c new file mode 100644 index 00000000..35dd72dc --- /dev/null +++ b/frameworks/modular/module.c @@ -0,0 +1,164 @@ +/* Copyright (c) 2017, ARM Limited. All rights reserved. + * + * Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include "module.h" + +#define MODULE_FRAMEWORK_VERSION 0x00010000UL +ODP_SUBSYSTEM_DEFINE(module, "module framework", MODULE_FRAMEWORK_VERSION); + +/* Keep it simple, allow one registration session at a time. */ +static struct { + odp_rwlock_t lock; + odp_subsystem_t *subsystem; + odp_module_base_t *module; +} registration = { + .lock = ODP_RWLOCK_UNLOCKED, + .subsystem = NULL, + .module = NULL, +}; + +#define REGISTRATION_SANITY_CHECK(subsystem, module) \ +do { \ + if (subsystem == NULL || module == NULL) \ + return -ENOENT; \ + \ + if (!list_node_detached(&module->list)) { \ + printf("module %s was already registered.\n", \ + module->name); \ + return -EAGAIN; \ + } \ +} while (0) + +/* Module is linked statically or dynamically, and are loaded by + * program loader (execve) or dynamic linker/loader (ld.so) + * + * subsystem_register_module() should complete the whole registration + * session and link the module into subsystem's module array. + */ +static int linker_register_module( + odp_subsystem_t *subsystem, odp_module_base_t *module) +{ + REGISTRATION_SANITY_CHECK(subsystem, module); + + /* Allow one registration session at a time */ + odp_rwlock_write_lock(®istration.lock); + + /* Block the subsystem API calls in load new + * implementation modules. */ + odp_rwlock_write_lock(&subsystem->lock); + module->handler = NULL; /* no DSO handler */ + list_add_tail(&subsystem->modules, &module->list); + odp_rwlock_write_unlock(&subsystem->lock); + + odp_rwlock_write_unlock(®istration.lock); + return 0; +} + +static int (*do_register_module)(odp_subsystem_t *, odp_module_base_t *) + = &linker_register_module; + +static int loader_register_module( + odp_subsystem_t *subsystem, odp_module_base_t *module) +{ + REGISTRATION_SANITY_CHECK(subsystem, module); + + /* Registration session lock must be held by + * module_loader_start(). */ + if (odp_rwlock_write_trylock(®istration.lock) == 0) { + registration.subsystem = subsystem; + registration.module = module; + return 0; + } + + odp_rwlock_write_unlock(®istration.lock); + return -EACCES; +} + +void odp_module_loader_start(void) +{ + odp_rwlock_write_lock(®istration.lock); + + if (registration.module != NULL || + registration.subsystem != NULL) { + printf("module loader start warn, A previous " + "registration did not complete yet.\n"); + } + + registration.module = NULL; + registration.subsystem = NULL; + do_register_module = &loader_register_module; +} + +void odp_module_loader_end(void) +{ + if (registration.module != NULL || + registration.subsystem != NULL) { + printf("module loader end warn, A previous " + "registration did not complete yet.\n"); + } + + registration.module = NULL; + registration.subsystem = NULL; + do_register_module = &linker_register_module; + + odp_rwlock_write_unlock(®istration.lock); +} + +int odp_module_install(void *dso, bool active) +{ + /* Bottom halves of the registration, context exclusion + * is guaranteed by module_loader_start() + */ + if (0 == odp_rwlock_write_trylock(®istration.lock)) { + odp_subsystem_t *subsystem = registration.subsystem; + odp_module_base_t *module = registration.module; + + if (subsystem != NULL && module != NULL) { + odp_rwlock_write_lock(&subsystem->lock); + + module->handler = dso; + list_add_tail(&subsystem->modules, &module->list); + + /* install as active implementation */ + if (active) /* warn: replaceable */ + subsystem->active = module; + + odp_rwlock_write_unlock(&subsystem->lock); + } + + registration.subsystem = NULL; + registration.module = NULL; + return 0; + } + + odp_rwlock_write_unlock(®istration.lock); + return -EACCES; +} + +int odp_module_abandon(void) +{ + /* Bottom halves of the registration, context exclusion + * is guaranteed by module_loader_start() + */ + if (0 == odp_rwlock_write_trylock(®istration.lock)) { + registration.subsystem = NULL; + registration.module = NULL; + return 0; + } + + odp_rwlock_write_unlock(®istration.lock); + return -EACCES; +} + +int __subsystem_register_module( + odp_subsystem_t *subsystem, odp_module_base_t *module) +{ + return do_register_module(subsystem, module); +} diff --git a/frameworks/modular/module.h b/frameworks/modular/module.h new file mode 100644 index 00000000..f8062ea9 --- /dev/null +++ b/frameworks/modular/module.h @@ -0,0 +1,296 @@ +/* Copyright (c) 2017, ARM Limited. All rights reserved. + * + * Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * Modular framework solves the problem of choosing a module + * from multiple modules of a subsystem. + * + * The choice is available during compile time or during runtime + * or initialization. The runtime choice could be using shared + * libraries or dynamic loadable libraries. + * + * Multiple modules of the same subsystem can be built into + * individual static libraries(.a), shared libraries(.so) to be + * dynamically linked or loaded, and use constructor functions + * to register themselves. + * + * A subsystem can choose one active module and provide APIs to + * switch between modules. + * + * Alternatively, subsystem can load multiple modules and + * determine the APIs route in runtime. + * + * In order to gain full possible performance, the subsystem + * allows for choosing a specific module at compile time. + * This eliminates the need to choose the module using function + * pointer table. + * + * This framework tries to minimizes dependencies to the linked + * list and rwlock facilities only. + */ + +#ifndef MODULE_H +#define MODULE_H + +#include +#include +#include "list.h" + +/* Forward declaration */ +typedef struct odp_module_base odp_module_base_t; + +/* Subsystem */ +typedef struct { + odp_rwlock_t lock; + uint32_t version; + const char *name; + const char *description; + struct list_head modules; + odp_module_base_t *active; +} odp_subsystem_t; + +/* Internally construct subsystem instance name */ +#define __subsystem(name) odp_ ## name ## _subsystem + +/* Declare an ODP subsystem in header file */ +#define ODP_SUBSYSTEM_DECLARE(name) \ + extern odp_subsystem_t __subsystem(name) + +/* Define an ODP subsystem in source file */ +#define ODP_SUBSYSTEM_DEFINE(_name, _description, _version) \ + odp_subsystem_t __subsystem(_name) = \ + { \ + .lock = ODP_RWLOCK_UNLOCKED, \ + .name = # _name, \ + .version = _version, \ + .description = _description, \ + } + +/* Internally construct subsystem API name */ +#define __odp_api(subsystem, api) odp_ ## subsystem ##_## api + +/* Subsystem API prototype name */ +#define odp_api_proto(subsystem, api) __odp_api(subsystem, api ## _proto_t) + +/* Subsystem API declaration */ +#define ODP_SUBSYSTEM_API(name, _return, api, ...) \ + extern _return __odp_api(name, api)(__VA_ARGS__); \ + typedef _return (*odp_api_proto(name, api))(__VA_ARGS__) + +/* Subsystem API stubs are weak */ +#define ODP_SUBSYSTEM_API_STUB(name, api) \ + __attribute__((weak)) __odp_api(name, api) + +/* In case a subsystem module are built as static libraries(.a) + * or preload dynamic libraries(.so), the module can use this + * macro to override the APIs weak stubs. + */ +#define ODP_SUBSYSTEM_API_OVERRIDE(name, api, _alias) \ + __attribute__((alias(#_alias))) __odp_api(name, api) + +#define odp_subsystem_constructor(name) \ + do { \ + odp_rwlock_init(&__subsystem(name).lock); \ + list_head_init(&__subsystem(name).modules); \ + __subsystem(name).active = NULL; \ + } while (0) + +#define ODP_SUBSYSTEM_CONSTRUCTOR(name) \ + static void __attribute__((constructor(101))) \ + odp_ ## name ## _subsystem_constructor(void) + +#define odp_subsystem_lock(access, name) \ + odp_rwlock_ ## access ## _lock(&__subsystem(name).lock) + +#define odp_subsystem_unlock(access, name) \ + odp_rwlock_ ## access ## _unlock(&__subsystem(name).lock) + +/* Base class to all inherited subsystem module classes */ +struct odp_module_base { + struct list_node list; + const char *name; + void *handler; /* DSO */ + int (*init_local)(void); + int (*term_local)(void); + int (*init_global)(void); + int (*term_global)(void); +}; + +/* It is required to define subsystem module class with the + * base class as its 1st member and named as "base", and also + * use ODP_MODULE_CLASS(subsystem) to create the association + * between module class name and subsystem name, like: + * + * typedef ODP_MODULE_CLASS(subsystem) { + * odp_module_base_t base; + * ...new members... + * } new_module_t; // Here pick the name you like freely + * + * It also supports forward declaration like: + * + * // Forward declaration + * typedef ODP_MODULE_CLASS(subsystem) new_module_t; + * // Laterly comes the definition + * ODP_MODULE_CLASS(subsystem) { + * odp_module_base_t base; + * ...new members... + * } + * + * Then in preprocessor macros when we have the subsystem name + * we can recover the module class type information, like: + * + * #define MACRO(subsystem) + * do { + * ODP_MODULE_CLASS(subsystem) *mod = NULL; + * odp_subsystem_foreach_module(subsystem, mod) { + * mod->xxx; // access the module class + * } + * } while(0) + */ +#define ODP_MODULE_CLASS(subsystem) struct odp_ ## subsystem ## _module + +/* Below macros assume that all subsystem module classes have + * odp_module_base_t as their 1st member named "base". + * + * This greatly reduces the complexity for module list iteration + * and module pointer recovery from its list_node member by a forced + * type conversion instead of complex calls to container_of() etc. + */ +#define __force_cast(module, node) \ + ((typeof(module))((void *)(node))) + +#define __foreach_module(pos, head) \ + for (pos = __force_cast(pos, (head)->node.next); \ + pos != __force_cast(pos, head); \ + pos = __force_cast(pos, (pos)->base.list.next)) + +#define __foreach_module_safe(pos, n, head) \ + for (pos = __force_cast(pos, (head)->node.next), \ + n = __force_cast(pos, (pos)->base.list.next); \ + pos != __force_cast(pos, head); \ + pos = n, n = __force_cast(next, (next)->base.list.next)) + +#define odp_subsystem_active_module(name, mod) \ + __force_cast(mod, __subsystem(name).active) + +#define odp_subsystem_foreach_module(name, mod) \ + __foreach_module(mod, &__subsystem(name).modules) + +#define odp_subsystem_foreach_module_safe(name, mod, next) \ + __foreach_module_safe(mod, next, &__subsystem(name).modules) + +#define odp_module_constructor(mod) list_node_init(&(mod)->base.list) + +/* Module constructors should be late than subsystem constructors, + * in statically linked scenarios (both subsystems and modules are + * linked statically). thus the priority 102 compared to the above + * subsystem constructor priority 101. + */ +#define ODP_MODULE_CONSTRUCTOR(name) \ + static void __attribute__((constructor(102))) \ + odp_ ## name ## _module_constructor(void) + +/* All subsystems' initialization and termination routines are + * the same, provide template to help generate similar routines + * automatically, examples: + * + * ODP_SUBSYSTEM_FOREACH_TEMPLATE(subsystem, init_global, DBG) + * will generate a function walk through all the modules of the + * subsystem and invoke init_global method for each. + */ +#define ODP_SUBSYSTEM_FOREACH_TEMPLATE(subs, method, print) \ +static int odp_ ## subs ##_## method(bool continue_on_errors) \ +{ \ + int result = 0; \ + ODP_MODULE_CLASS(subs) * mod = NULL; \ + \ + odp_subsystem_lock(read, subs); \ + odp_subsystem_foreach_module(subs, mod) { \ + result = mod->base.method ? \ + mod->base.method() : 0; \ + if (result < 0) { \ + print("error %d to %s subsystem %s " \ + "module %s.\n", result, #method, \ + __subsystem(subs).name, \ + mod->base.name); \ + \ + if (continue_on_errors) \ + continue; \ + else \ + goto done; \ + } \ + } \ +done: \ + odp_subsystem_unlock(read, subs); \ + return result; \ +} + +/* Subsystem Modules Registration + * + * odp_subsystem_register_module() are called by all modules in their + * constructors, whereas the modules could be: + * + * 1) built as static libraries(.a) and linked statically, or + * built as shared libraries(.so) and linked dynamically. + * + * odp_subsystem_register_module() should complete the whole + * registration session and link the module into subsystem's + * module array. + * + * 2) built as shared libraries(.so) and loaded by a module loader + * in runtime with libdl APIs + * + * The whole registration session needs to be split to aim the + * module loader to properly handle dlopen() returns, and save + * the DSO handler into module's data structure. + * + * The module loader should program in this way: + * odp_module_loader_start(); + * ...... + * for each module + * handler = dlopen(module); + * // The module constructor runs before dlopen() returns + * // which in turn calls odp_subsystem_register_module() + * if (handler is valid) + * odp_module_install(handler); + * else + * odp_module_abandon(); + * ...... + * odp_module_loader_end(); + */ + +void odp_module_loader_start(void); +void odp_module_loader_end(void); + +int odp_module_install(void *, bool active); +int odp_module_abandon(void); + +#define __maybe_unused __attribute__((unused)) +static inline void __subsystem_set_active( + odp_subsystem_t *subsystem __maybe_unused, + odp_module_base_t *module __maybe_unused) +{ +#if defined(IM_ACTIVE_MODULE) + subsystem->active = base; +#endif +} + +int __subsystem_register_module( + odp_subsystem_t *, odp_module_base_t *); + +/* Macro to allow polymorphism on module classes */ +#define odp_subsystem_register_module(name, module) \ +({ \ + odp_module_base_t *base = &(module)->base; \ + __subsystem_register_module(&__subsystem(name), base); \ + __subsystem_set_active(&__subsystem(name), base); \ +}) + +#endif diff --git a/include/odp/api/spec/atomic.h b/include/odp/api/spec/atomic.h index 408829df..a8233d24 100644 --- a/include/odp/api/spec/atomic.h +++ b/include/odp/api/spec/atomic.h @@ -59,6 +59,11 @@ extern "C" { * Atomic 32-bit unsigned integer */ +/** + * @def ODP_ATOMIC_INIT + * Atomic initializer: odp_atomic_xx_t atomic = ODP_ATOMIC_INIT(v); + */ + /* * 32-bit operations in RELAXED memory ordering * -------------------------------------------- diff --git a/include/odp/api/spec/rwlock.h b/include/odp/api/spec/rwlock.h index ff8a3f27..01ee74d9 100644 --- a/include/odp/api/spec/rwlock.h +++ b/include/odp/api/spec/rwlock.h @@ -36,6 +36,10 @@ extern "C" { * ODP reader/writer lock */ +/** + * @def ODP_RWLOCK_UNLOCKED + * RW lock initializer: odp_rwlock_t lock = ODP_RWLOCK_UNLOCKED; + */ /** * Initialize a reader/writer lock. diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index ba4a31ea..7794d0b4 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -6,6 +6,7 @@ include $(top_srcdir)/platform/@with_platform@/Makefile.inc AM_CFLAGS += -I$(srcdir)/include AM_CFLAGS += -I$(top_srcdir)/include +AM_CFLAGS += -I$(top_srcdir)/frameworks/modular AM_CFLAGS += -I$(top_srcdir)/include/odp/arch/@ARCH_ABI@ AM_CFLAGS += -I$(top_builddir)/include AM_CFLAGS += -Iinclude @@ -292,6 +293,13 @@ if HAVE_PCAP __LIB__libodp_linux_la_SOURCES += pktio/pcap.c endif +# Build modular framework into odp-linux library +modularframeworkdir = $(top_srcdir)/frameworks/modular +noinst_HEADERS += $(modularframeworkdir)/list.h \ + $(modularframeworkdir)/module.h + +__LIB__libodp_linux_la_SOURCES += ../../frameworks/modular/module.c + __LIB__libodp_linux_la_LIBADD = $(ATOMIC_LIBS) # Create symlink for ABI header files. Application does not need to use the arch diff --git a/platform/linux-generic/include/odp/api/plat/atomic_types.h b/platform/linux-generic/include/odp/api/plat/atomic_types.h index a674ac99..86c9e5b0 100644 --- a/platform/linux-generic/include/odp/api/plat/atomic_types.h +++ b/platform/linux-generic/include/odp/api/plat/atomic_types.h @@ -81,6 +81,8 @@ typedef struct odp_atomic_u64_s odp_atomic_u64_t; typedef struct odp_atomic_u32_s odp_atomic_u32_t; +#define ODP_ATOMIC_INIT(a) { .v = a } + #ifdef __cplusplus } #endif diff --git a/platform/linux-generic/include/odp/api/plat/rwlock_types.h b/platform/linux-generic/include/odp/api/plat/rwlock_types.h index f7dc0449..2c1f3660 100644 --- a/platform/linux-generic/include/odp/api/plat/rwlock_types.h +++ b/platform/linux-generic/include/odp/api/plat/rwlock_types.h @@ -30,6 +30,8 @@ struct odp_rwlock_s { typedef struct odp_rwlock_s odp_rwlock_t; +#define ODP_RWLOCK_UNLOCKED { .cnt = ODP_ATOMIC_INIT(0) } + #ifdef __cplusplus } #endif