Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 23 Nov 2012 13:47:42 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r243451 - in projects/counters/sys: conf kern sys
Message-ID:  <201211231347.qANDlg7N024809@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: glebius
Date: Fri Nov 23 13:47:41 2012
New Revision: 243451
URL: http://svnweb.freebsd.org/changeset/base/243451

Log:
    Prototype a simple API for per-cpu counters, right now
  only 64-bit.
  
    A counter can be allocated, zeroed, freed, incremented
  and decremented.
  
    The incremention/decremention functions are going to MD.
  Right now amd64 implementation is put into MI file, while
  the project branch is pre-alpha state.
  
    A dummy implementation on 64-bit arch would pin to current
  CPU, calculate address of counter for this cpu, update it
  and unpin. We may provide a racy non-pinning interface, that
  can lead the update going to other's CPU counter.
  
    A smart implementation for amd64 does a one-instruction
  update, thus doesn't require any pinning. This is achieved
  due to the fact that UMA_ZONE_PCPU zone guarantees us that
  per-cpu counters are aligned by the size of struct pcpu
  from each other. And we have address of static struct pcpu
  in %gs register always. This nice implementation is submitted
  by kib@.
  
    Implementation for 32-bit arches would require critical
  section for update.

Added:
  projects/counters/sys/kern/subr_counter.c   (contents, props changed)
  projects/counters/sys/sys/counter.h   (contents, props changed)
Modified:
  projects/counters/sys/conf/files

Modified: projects/counters/sys/conf/files
==============================================================================
--- projects/counters/sys/conf/files	Fri Nov 23 13:43:51 2012	(r243450)
+++ projects/counters/sys/conf/files	Fri Nov 23 13:47:41 2012	(r243451)
@@ -2667,6 +2667,7 @@ kern/subr_blist.c		standard
 kern/subr_bus.c			standard
 kern/subr_bufring.c		standard
 kern/subr_clock.c		standard
+kern/subr_counter.c		standard
 kern/subr_devstat.c		standard
 kern/subr_disk.c		standard
 kern/subr_eventhandler.c	standard

Added: projects/counters/sys/kern/subr_counter.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/counters/sys/kern/subr_counter.c	Fri Nov 23 13:47:41 2012	(r243451)
@@ -0,0 +1,82 @@
+/*-
+ * Copyright (c) 2012 Gleb Smirnoff <glebius@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/counter.h>
+#include <vm/uma.h>
+ 
+static uma_zone_t uint64_pcpu_zone;
+
+void
+counter_u64_zero(counter_u64_t c)
+{
+
+	for (int i = 0; i < mp_ncpus; i++)
+		*(uint64_t *)((char *)c + sizeof(struct pcpu) * i) = 0;
+}
+
+uint64_t
+counter_u64_fetch(counter_u64_t c)
+{
+	uint64_t r;
+
+	r = 0;
+	for (int i = 0; i < mp_ncpus; i++)
+		r += *(uint64_t *)((char *)c + sizeof(struct pcpu) * i);
+
+	return (r);
+}
+
+counter_u64_t
+counter_u64_alloc(int flags)
+{
+	counter_u64_t r;
+
+	r = uma_zalloc(uint64_pcpu_zone, flags);
+	if (r)
+		counter_u64_zero(r);
+
+	return (r);
+}
+
+void
+counter_u64_free(counter_u64_t c)
+{
+
+	uma_zfree(uint64_pcpu_zone, c);
+}
+
+static void
+counter_startup()
+{
+
+	uint64_pcpu_zone = uma_zcreate("uint64 pcpu", sizeof(uint64_t),
+	    NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_PCPU);
+}
+SYSINIT(counter, SI_SUB_KMEM, SI_ORDER_ANY, counter_startup, NULL);

Added: projects/counters/sys/sys/counter.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/counters/sys/sys/counter.h	Fri Nov 23 13:47:41 2012	(r243451)
@@ -0,0 +1,70 @@
+/*-
+ * Copyright (c) 2012 Gleb Smirnoff <glebius@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __SYS_COUNTER_H__
+#define __SYS_COUNTER_H__
+
+#include <sys/param.h>
+#include <sys/pcpu.h>
+#include <sys/smp.h>
+
+typedef uint64_t * counter_u64_t;
+
+/*
+ * XXXGL: to be MD. Just testing now.
+ */
+extern struct pcpu __pcpu[1];
+
+static __inline void
+counter_u64_inc(counter_u64_t c, uint64_t inc)
+{
+
+	__asm __volatile("addq\t%1,%%gs:(%0)" : :
+	    "r" ((char *)c - (char *)&__pcpu[0]),
+	    "r" (inc));
+}
+
+static __inline void
+counter_u64_dec(counter_u64_t c, uint64_t dec)
+{
+
+	__asm __volatile("subq\t%1,%%gs:(%0)" : :
+	    "r" ((char *)c - (char *)&__pcpu[0]),
+	    "r" (dec));
+}
+
+counter_u64_t	counter_u64_alloc(int);
+void		counter_u64_free(counter_u64_t);
+
+void		counter_u64_zero(counter_u64_t);
+uint64_t	counter_u64_fetch(counter_u64_t);
+
+#endif	/* ! __SYS_COUNTER_H__ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201211231347.qANDlg7N024809>