Commit | Line | Data |
---|---|---|
2754583e MD |
1 | /* |
2 | * lttng-clock.c | |
3 | * | |
4 | * Copyright (C) 2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
5 | * | |
6 | * This library is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU Lesser General Public | |
8 | * License as published by the Free Software Foundation; only | |
9 | * version 2.1 of the License. | |
10 | * | |
11 | * This library is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * Lesser General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU Lesser General Public | |
17 | * License along with this library; if not, write to the Free Software | |
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
19 | */ | |
20 | ||
21 | #include <linux/module.h> | |
22 | #include <linux/kmod.h> | |
23 | #include <linux/mutex.h> | |
24 | ||
25 | #include "wrapper/trace-clock.h" | |
26 | #include "lttng-events.h" | |
27 | #include "lttng-tracer.h" | |
28 | ||
29 | struct lttng_trace_clock *lttng_trace_clock; | |
30 | EXPORT_SYMBOL_GPL(lttng_trace_clock); | |
31 | ||
32 | static DEFINE_MUTEX(clock_mutex); | |
33 | static struct module *lttng_trace_clock_mod; /* plugin */ | |
34 | static int clock_used; /* refcount */ | |
35 | ||
36 | int lttng_clock_register_plugin(struct lttng_trace_clock *ltc, | |
37 | struct module *mod) | |
38 | { | |
39 | int ret = 0; | |
40 | ||
41 | mutex_lock(&clock_mutex); | |
42 | if (clock_used) { | |
43 | ret = -EBUSY; | |
44 | goto end; | |
45 | } | |
46 | if (lttng_trace_clock_mod) { | |
47 | ret = -EEXIST; | |
48 | goto end; | |
49 | } | |
50 | /* set clock */ | |
51 | ACCESS_ONCE(lttng_trace_clock) = ltc; | |
52 | lttng_trace_clock_mod = mod; | |
53 | end: | |
54 | mutex_unlock(&clock_mutex); | |
55 | return ret; | |
56 | } | |
57 | EXPORT_SYMBOL_GPL(lttng_clock_register_plugin); | |
58 | ||
59 | void lttng_clock_unregister_plugin(struct lttng_trace_clock *ltc, | |
60 | struct module *mod) | |
61 | { | |
62 | mutex_lock(&clock_mutex); | |
63 | WARN_ON_ONCE(clock_used); | |
64 | if (!lttng_trace_clock_mod) { | |
65 | goto end; | |
66 | } | |
67 | WARN_ON_ONCE(lttng_trace_clock_mod != mod); | |
68 | ||
69 | ACCESS_ONCE(lttng_trace_clock) = NULL; | |
70 | lttng_trace_clock_mod = NULL; | |
71 | end: | |
72 | mutex_unlock(&clock_mutex); | |
73 | } | |
74 | EXPORT_SYMBOL_GPL(lttng_clock_unregister_plugin); | |
75 | ||
76 | void lttng_clock_ref(void) | |
77 | { | |
78 | mutex_lock(&clock_mutex); | |
79 | clock_used++; | |
80 | if (lttng_trace_clock_mod) { | |
81 | int ret; | |
82 | ||
83 | ret = try_module_get(lttng_trace_clock_mod); | |
84 | if (!ret) { | |
85 | printk(KERN_ERR "LTTng-clock cannot get clock plugin module\n"); | |
86 | ACCESS_ONCE(lttng_trace_clock) = NULL; | |
87 | lttng_trace_clock_mod = NULL; | |
88 | } | |
89 | } | |
90 | mutex_unlock(&clock_mutex); | |
91 | } | |
92 | EXPORT_SYMBOL_GPL(lttng_clock_ref); | |
93 | ||
94 | void lttng_clock_unref(void) | |
95 | { | |
96 | mutex_lock(&clock_mutex); | |
97 | clock_used--; | |
98 | if (lttng_trace_clock_mod) | |
99 | module_put(lttng_trace_clock_mod); | |
100 | mutex_unlock(&clock_mutex); | |
101 | } | |
102 | EXPORT_SYMBOL_GPL(lttng_clock_unref); | |
103 | ||
104 | MODULE_LICENSE("GPL and additional rights"); | |
105 | MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers@efficios.com>"); | |
106 | MODULE_DESCRIPTION("LTTng Clock"); | |
107 | MODULE_VERSION(__stringify(LTTNG_MODULES_MAJOR_VERSION) "." | |
108 | __stringify(LTTNG_MODULES_MINOR_VERSION) "." | |
109 | __stringify(LTTNG_MODULES_PATCHLEVEL_VERSION) | |
110 | LTTNG_MODULES_EXTRAVERSION); |