root/arch/mips/kernel/spinlock_test.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ss_get
  2. multi_other
  3. multi_get
  4. spinlock_test

   1 // SPDX-License-Identifier: GPL-2.0
   2 #include <linux/init.h>
   3 #include <linux/kthread.h>
   4 #include <linux/hrtimer.h>
   5 #include <linux/fs.h>
   6 #include <linux/debugfs.h>
   7 #include <linux/export.h>
   8 #include <linux/spinlock.h>
   9 #include <asm/debug.h>
  10 
  11 static int ss_get(void *data, u64 *val)
  12 {
  13         ktime_t start, finish;
  14         int loops;
  15         int cont;
  16         DEFINE_RAW_SPINLOCK(ss_spin);
  17 
  18         loops = 1000000;
  19         cont = 1;
  20 
  21         start = ktime_get();
  22 
  23         while (cont) {
  24                 raw_spin_lock(&ss_spin);
  25                 loops--;
  26                 if (loops == 0)
  27                         cont = 0;
  28                 raw_spin_unlock(&ss_spin);
  29         }
  30 
  31         finish = ktime_get();
  32 
  33         *val = ktime_us_delta(finish, start);
  34 
  35         return 0;
  36 }
  37 
  38 DEFINE_SIMPLE_ATTRIBUTE(fops_ss, ss_get, NULL, "%llu\n");
  39 
  40 
  41 
  42 struct spin_multi_state {
  43         raw_spinlock_t lock;
  44         atomic_t start_wait;
  45         atomic_t enter_wait;
  46         atomic_t exit_wait;
  47         int loops;
  48 };
  49 
  50 struct spin_multi_per_thread {
  51         struct spin_multi_state *state;
  52         ktime_t start;
  53 };
  54 
  55 static int multi_other(void *data)
  56 {
  57         int loops;
  58         int cont;
  59         struct spin_multi_per_thread *pt = data;
  60         struct spin_multi_state *s = pt->state;
  61 
  62         loops = s->loops;
  63         cont = 1;
  64 
  65         atomic_dec(&s->enter_wait);
  66 
  67         while (atomic_read(&s->enter_wait))
  68                 ; /* spin */
  69 
  70         pt->start = ktime_get();
  71 
  72         atomic_dec(&s->start_wait);
  73 
  74         while (atomic_read(&s->start_wait))
  75                 ; /* spin */
  76 
  77         while (cont) {
  78                 raw_spin_lock(&s->lock);
  79                 loops--;
  80                 if (loops == 0)
  81                         cont = 0;
  82                 raw_spin_unlock(&s->lock);
  83         }
  84 
  85         atomic_dec(&s->exit_wait);
  86         while (atomic_read(&s->exit_wait))
  87                 ; /* spin */
  88         return 0;
  89 }
  90 
  91 static int multi_get(void *data, u64 *val)
  92 {
  93         ktime_t finish;
  94         struct spin_multi_state ms;
  95         struct spin_multi_per_thread t1, t2;
  96 
  97         ms.lock = __RAW_SPIN_LOCK_UNLOCKED("multi_get");
  98         ms.loops = 1000000;
  99 
 100         atomic_set(&ms.start_wait, 2);
 101         atomic_set(&ms.enter_wait, 2);
 102         atomic_set(&ms.exit_wait, 2);
 103         t1.state = &ms;
 104         t2.state = &ms;
 105 
 106         kthread_run(multi_other, &t2, "multi_get");
 107 
 108         multi_other(&t1);
 109 
 110         finish = ktime_get();
 111 
 112         *val = ktime_us_delta(finish, t1.start);
 113 
 114         return 0;
 115 }
 116 
 117 DEFINE_SIMPLE_ATTRIBUTE(fops_multi, multi_get, NULL, "%llu\n");
 118 
 119 static int __init spinlock_test(void)
 120 {
 121         debugfs_create_file("spin_single", S_IRUGO, mips_debugfs_dir, NULL,
 122                             &fops_ss);
 123         debugfs_create_file("spin_multi", S_IRUGO, mips_debugfs_dir, NULL,
 124                             &fops_multi);
 125         return 0;
 126 }
 127 device_initcall(spinlock_test);

/* [<][>][^][v][top][bottom][index][help] */