From patchwork Mon Mar 18 13:13:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Stubbs X-Patchwork-Id: 1057875 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-498036-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="r9q3Cjbp"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44NGqy4CbSz9sBV for ; Tue, 19 Mar 2019 00:14:52 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :subject:to:message-id:date:mime-version:content-type; q=dns; s= default; b=YcHRyTFuIH1ez3u+lxYftBLhNpMy9r4aSf9Xn+WYDVpnYIO2I2IvK SYKIubcTO9SGzZzKDVm19fprLGUlEob9tzAUw4Vtz6pOJLZnsuFjntW7FBjz2qoP wkVMlR7WJd/o24RYxK8jINj4cq7bFcqJBBmQFcHutPU1jH0OgSyKMA= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :subject:to:message-id:date:mime-version:content-type; s= default; bh=0HEEsbWdi/rN4umwpCA9wB2+pAY=; b=r9q3Cjbpo+PusUPjR2RL xjXqyUfZCQY/oOrvgt9t2zXshwYMLMfCvBj8s4jSQkK5IDqC6rJ0z0ptadpPUca1 7g5Pw/luYVTV5dFvWbn7zPGbpRVPrIG+nYn2qAmVJTqTOzNK5TWTHgpKDT90xU5o YX51/TqBe7NFpU07HHiJ9Qk= Received: (qmail 40367 invoked by alias); 18 Mar 2019 13:14:44 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 39715 invoked by uid 89); 18 Mar 2019 13:14:44 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-17.2 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=mentor, stderr, resume, device X-HELO: relay1.mentorg.com Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 18 Mar 2019 13:14:42 +0000 Received: from nat-ies.mentorg.com ([192.94.31.2] helo=svr-ies-mbx-01.mgc.mentorg.com) by relay1.mentorg.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-SHA384:256) id 1h5s6C-0004IQ-9C from Andrew_Stubbs@mentor.com for gcc-patches@gcc.gnu.org; Mon, 18 Mar 2019 06:14:40 -0700 Received: from [127.0.0.1] (137.202.0.90) by svr-ies-mbx-01.mgc.mentorg.com (139.181.222.1) with Microsoft SMTP Server (TLS) id 15.0.1320.4; Mon, 18 Mar 2019 13:13:50 +0000 From: Andrew Stubbs Subject: [gcn commit] Implement circular output buffer To: "gcc-patches@gcc.gnu.org" Message-ID: <49c2acae-1049-979c-cf7e-7049fa692ceb@codesourcery.com> Date: Mon, 18 Mar 2019 13:13:49 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.5.1 MIME-Version: 1.0 This patch removes the arbitrary 1000-line output limit imposed in the stdout/stderr output mechanism. The implementation is backward compatible with the old counterpart implementation already present in newlib, but I'll be updating that shortly. I've run a GCN testrun with no regressions. Andrew Stubbs Mentor Graphics / CodeSourcery Implement circular print buffer. 2019-03-18 Andrew Stubbs gcc/ * config/gcn/gcn-run.c (struct output): Make next_output unsigned. Extend queue to 1024 entries. Add "consumed" field. (gomp_print_output): Remove print_index parameter. Add final parameter. Change limit to unsigned. Use consumed field to implement circular buffer. Detect interrupted print in final pass. Flush output at the end. (run): Update gomp_print_output usage. (main): Initialize kernargs->output_data.consumed. diff --git a/gcc/config/gcn/gcn-run.c b/gcc/config/gcn/gcn-run.c index 58089843ef8..00a71014c20 100644 --- a/gcc/config/gcn/gcn-run.c +++ b/gcc/config/gcn/gcn-run.c @@ -601,7 +601,7 @@ struct kernargs struct output { int return_value; - int next_output; + unsigned int next_output; struct printf_data { int written; @@ -613,7 +613,8 @@ struct kernargs double dvalue; char text[128]; }; - } queue[1000]; + } queue[1024]; + unsigned int consumed; } output_data; struct heap @@ -624,21 +625,34 @@ struct kernargs }; /* Print any console output from the kernel. - We print all entries from print_index to the next entry without a "written" - flag. Subsequent calls should use the returned print_index value to resume - from the same point. */ + We print all entries from "consumed" to the next entry without a "written" + flag, or "next_output" is reached. The buffer is circular, but the + indices are absolute. It is assumed the kernel will stop writing data + if "next_output" wraps (becomes smaller than "consumed"). */ void -gomp_print_output (struct kernargs *kernargs, int *print_index) +gomp_print_output (struct kernargs *kernargs, bool final) { - int limit = (sizeof (kernargs->output_data.queue) - / sizeof (kernargs->output_data.queue[0])); + unsigned int limit = (sizeof (kernargs->output_data.queue) + / sizeof (kernargs->output_data.queue[0])); - int i; - for (i = *print_index; i < limit; i++) + unsigned int from = __atomic_load_n (&kernargs->output_data.consumed, + __ATOMIC_ACQUIRE); + unsigned int to = kernargs->output_data.next_output; + + if (from > to) + { + /* Overflow. */ + if (final) + printf ("GCN print buffer overflowed.\n"); + return; + } + + unsigned int i; + for (i = from; i < to; i++) { - struct printf_data *data = &kernargs->output_data.queue[i]; + struct printf_data *data = &kernargs->output_data.queue[i%limit]; - if (!data->written) + if (!data->written && !final) break; switch (data->type) @@ -655,16 +669,16 @@ gomp_print_output (struct kernargs *kernargs, int *print_index) case 3: printf ("%.128s%.128s", data->msg, data->text); break; + default: + printf ("GCN print buffer error!\n"); + break; } data->written = 0; + __atomic_store_n (&kernargs->output_data.consumed, i+1, + __ATOMIC_RELEASE); } - - if (*print_index < limit && i == limit - && kernargs->output_data.next_output > limit) - printf ("WARNING: GCN print buffer exhausted.\n"); - - *print_index = i; + fflush (stdout); } /* Execute an already-loaded kernel on the device. */ @@ -711,16 +725,15 @@ run (void *kernargs) hsa_fns.hsa_queue_store_write_index_relaxed_fn (queue, index + 1); hsa_fns.hsa_signal_store_relaxed_fn (queue->doorbell_signal, index); /* Kernel running ...... */ - int print_index = 0; while (hsa_fns.hsa_signal_wait_relaxed_fn (signal, HSA_SIGNAL_CONDITION_LT, 1, 1000000, HSA_WAIT_STATE_ACTIVE) != 0) { usleep (10000); - gomp_print_output (kernargs, &print_index); + gomp_print_output (kernargs, false); } - gomp_print_output (kernargs, &print_index); + gomp_print_output (kernargs, true); if (debug) fprintf (stderr, "Kernel exited\n"); @@ -797,6 +810,7 @@ main (int argc, char *argv[]) for (unsigned i = 0; i < (sizeof (kernargs->output_data.queue) / sizeof (kernargs->output_data.queue[0])); i++) kernargs->output_data.queue[i].written = 0; + kernargs->output_data.consumed = 0; int offset = 0; for (int i = 0; i < kernel_argc; i++) {