svn commit: r243451 - in projects/counters/sys: conf kern sys
Gleb Smirnoff
glebius at FreeBSD.org
Fri Nov 23 13:47:42 UTC 2012
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 at .
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 at 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 at 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__ */
More information about the svn-src-projects
mailing list