Phong, this may be interesting for you.

Olga

---------- Forwarded message ----------
From: Vitaliy Gusev <gusev.vita...@nexenta.com>
Date: Mon, Aug 27, 2012 at 3:12 PM
Subject: [developer] [PATCH] kernel: "seqlock" syncronization primitive
To: garr...@damore.org
Cc: gusev.vita...@nexenta.com, develo...@lists.illumos.org,
gordon.r...@nexenta.com, mahr...@delphix.com, richl...@richlowe.net


# HG changeset patch
# User Vitaliy Gusev <gusev.vita...@nexenta.com>
# Date 1346072919 -14400
# Node ID aae4235aadf76a9cbe117ae391fb3831f8c0ec1b
# Parent  aeac1998cacba75a501e86ccf28f9e32cb9ed1c7
kernel: "seqlock" syncronization primitive

This is implementation of "seqlock". Idea was borrowed from the Linux kernel.

"seqlock" brings huge performance improvement. The case of usage - when there
are a lot of readers, but very raraly writers.

Readers enter to a cirtical-section without any atomic or LOCK operations, so
don't waste system bus. Therefore readers are very fast even on multi-CPUs
system.

Note, seqlock can be used only to protect non-pointers data:

     - numbers (char, short, int, long, long long, ...)
     - arrays
     - opaque data
     - flags

Example:

    struct data {
         seqlock_t lock;
         int uid;
         int map_uid;
   }

   struct data *data;

  /* data allocation and initialization */

  Reader:

       int seq;
       int uid, map_id;

       do {
           seq = seq_read_begin(&data->lock);

           uid = data->id;
           map_uid = data->uid;

     } while (seq_read_retry(&data->lock, seq));

     /* Have valid uid -> map_uid */


  Writer:

        seq_write_lock(&data->lock);
        data->uid = new_uid;
        data->map_uid = new_map_uid;
        seq_write_unlock(&data->lock);

diff -r aeac1998cacb -r aae4235aadf7 usr/src/uts/common/Makefile.files
--- a/usr/src/uts/common/Makefile.files Mon Aug 27 14:15:46 2012 +0400
+++ b/usr/src/uts/common/Makefile.files Mon Aug 27 17:08:39 2012 +0400
@@ -66,6 +66,7 @@ COMMON_CORE_OBJS +=           \
                rctl_proc.o     \
                rwlock.o        \
                seg_kmem.o      \
+               seqlock.o       \
                softint.o       \
                string.o        \
                strtol.o        \
diff -r aeac1998cacb -r aae4235aadf7 usr/src/uts/common/os/seqlock.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/os/seqlock.c   Mon Aug 27 17:08:39 2012 +0400
@@ -0,0 +1,66 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+/*
+ * Copyright 2012 Nexenta Systems, Inc.  All rights reserved.
+ *
+ * seqlock.c - Implementation of sequence lock algorithm.
+ */
+#include <sys/types.h>
+#include <sys/ddi.h>
+#include <sys/mutex.h>
+#include <sys/cpu.h>           /* for SMT_PAUSE */
+#include <sys/cpuvar.h>                /* for kpreempt */
+#include <sys/seqlock.h>
+
+void
+seq_init(seqlock_t *seqlock)
+{
+       seqlock->sequence = 0;
+       mutex_init(&seqlock->lock, NULL, MUTEX_DEFAULT, NULL);
+}
+
+void
+seq_destroy(seqlock_t *seqlock)
+{
+       mutex_destroy(&seqlock->lock);
+}
+
+int
+seq_read_begin(volatile seqlock_t *seqlock)
+{
+       int seq;
+again:
+       seq = seqlock->sequence;
+       if (seq & 0x1) {
+               SMT_PAUSE();
+               goto again;
+       }
+       membar_consumer();
+       return (seq);
+}
+
+void
+seq_write_lock(seqlock_t *seqlock)
+{
+       mutex_enter(&seqlock->lock);
+       kpreempt_disable();
+       seqlock->sequence++;
+       membar_producer();
+}
+
+void
+seq_write_unlock(seqlock_t *seqlock)
+{
+       seqlock->sequence++;
+       membar_producer();
+       kpreempt_enable();
+       mutex_exit(&seqlock->lock);
+}
diff -r aeac1998cacb -r aae4235aadf7 usr/src/uts/common/sys/seqlock.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/sys/seqlock.h  Mon Aug 27 17:08:39 2012 +0400
@@ -0,0 +1,63 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+/*
+ * Copyright 2012 Nexenta Systems, Inc.  All rights reserved.
+ *
+ * seqlock.h - Definitions of sequence lock algorithm.
+ *
+ * Example for reader:
+ *
+ * do {
+ *    int seq = seq_read_begin(&seqlock);
+ *    ...
+ * } while (seq_read_retry(&seqlock, seq));
+ *
+ */
+
+#ifndef        _SYS_SEQLOCK_H
+#define        _SYS_SEQLOCK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+#include <sys/mutex.h>
+#include <sys/atomic.h>                /* for membar_consumer() */
+
+typedef struct seqlock {
+       int      sequence;
+       kmutex_t lock;
+} seqlock_t;
+
+extern void seq_init(seqlock_t *);
+extern void seq_destroy(seqlock_t *);
+extern int  seq_read_begin(volatile seqlock_t *);
+
+/*
+ * Code under seq_write_lock() should be fast and
+ * must not call sleeping function
+ */
+extern void seq_write_lock(seqlock_t *);
+extern void seq_write_unlock(seqlock_t *);
+
+static boolean_t seq_read_retry(const seqlock_t *seqlock, int seq)
+{
+       membar_consumer();
+       return (seqlock->sequence != seq);
+}
+#pragma inline(seq_read_retry)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_SEQLOCK_H */


-------------------------------------------
illumos-developer
Archives: https://www.listbox.com/member/archive/182179/=now
RSS Feed: https://www.listbox.com/member/archive/rss/182179/21175218-fb99b1aa
Modify Your Subscription:
https://www.listbox.com/member/?member_id=21175218&id_secret=21175218-68edcfe3
Powered by Listbox: http://www.listbox.com


-- 
      ,   _                                    _   ,
     { \/`o;====-    Olga Kryzhanovska   -====;o`\/ }
.----'-/`-/     olga.kryzhanov...@gmail.com   \-`\-'----.
 `'-..-| /       http://twitter.com/fleyta     \ |-..-'`
      /\/\     Solaris/BSD//C/C++ programmer   /\/\
      `--`                                      `--`
_______________________________________________
ast-developers mailing list
ast-developers@research.att.com
https://mailman.research.att.com/mailman/listinfo/ast-developers

Reply via email to