[LinuxPPS] Locking code
Rodolfo Giometti
giometti at enneenne.com
Mon Nov 27 00:18:39 CET 2006
On Sun, Nov 26, 2006 at 10:57:11PM +0100, Rodolfo Giometti wrote:
>
> I just published new code with locking code. After that we should be
> ready to submit LinuxPPS to linux kernel main tree.
Ok guys, I should stop doing late-night-hacking since last patch was
__broken__! Sorry...
I just fixed bot git repository and the ntp-pps-2.6.19-rc2.diff patch
on my site, also attached you can find the new locking patch.
Ciao,
Rodolfo
--
GNU/Linux Solutions e-mail: giometti at enneenne.com
Linux Device Driver giometti at gnudd.com
Embedded Systems giometti at linux.it
UNIX programming phone: +39 349 2432127
-------------- next part --------------
diff --git a/drivers/pps/kapi.c b/drivers/pps/kapi.c
index 1593dd3..ca5fa4d 100644
--- a/drivers/pps/kapi.c
+++ b/drivers/pps/kapi.c
@@ -48,12 +48,12 @@ static void linuxpps_add_offeset(struct
/* --- Exported functions -------------------------------------------------- */
-int linuxpps_register_source(struct linuxpps_source_info_s *info, int default_params, int try_id)
+static inline int __linuxpps_register_source(struct linuxpps_source_info_s *info, int default_params, int try_id)
{
int i, ret;
if (try_id >= 0) {
- if (linuxpps_is_allocated(try_id)) {
+ if (__linuxpps_is_allocated(try_id)) {
err("source id %d busy", try_id);
return -EBUSY;
}
@@ -61,7 +61,7 @@ int linuxpps_register_source(struct linu
}
else {
for (i = 0; i < LINUXPPS_MAX_SOURCES; i++)
- if (!linuxpps_is_allocated(i))
+ if (!__linuxpps_is_allocated(i))
break;
if (i >= LINUXPPS_MAX_SOURCES) {
err("no free source ids");
@@ -97,12 +97,24 @@ int linuxpps_register_source(struct linu
return i;
}
-void linuxpps_unregister_source(struct linuxpps_source_info_s *info)
+int linuxpps_register_source(struct linuxpps_source_info_s *info, int default_params, int try_id)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&linuxpps_lock, flags);
+ ret = __linuxpps_register_source(info, default_params, try_id);
+ spin_unlock_irqrestore(&linuxpps_lock, flags);
+
+ return ret;
+}
+
+static inline void __linuxpps_unregister_source(struct linuxpps_source_info_s *info)
{
int i;
for (i = 0; i < LINUXPPS_MAX_SOURCES; i++)
- if (linuxpps_is_allocated(i) && linuxpps_source[i].info == info)
+ if (__linuxpps_is_allocated(i) && linuxpps_source[i].info == info)
break;
if (i >= LINUXPPS_MAX_SOURCES) {
@@ -115,10 +127,23 @@ void linuxpps_unregister_source(struct l
linuxpps_source[i].info = NULL;
}
+void linuxpps_unregister_source(struct linuxpps_source_info_s *info)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&linuxpps_lock, flags);
+ __linuxpps_unregister_source(info);
+ spin_unlock_irqrestore(&linuxpps_lock, flags);
+}
+
void linuxpps_event(int source, int event)
{
struct timespec ts;
+ /* In this function we shouldn't need locking at all since each PPS
+ * source arrives once per second and due the per-PPS source data
+ * array... */
+
/* First of all we get the time stamp... */
do_gettimeofday((struct timeval *) &ts);
ts.tv_nsec *= 1000; /* microseconds to nanoseconds */
diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c
index 867fb39..f5ba18b 100644
--- a/drivers/pps/pps.c
+++ b/drivers/pps/pps.c
@@ -32,6 +32,7 @@ #include <linux/pps.h>
/* --- Global variables ---------------------------------------------------- */
struct linuxpps_s linuxpps_source[LINUXPPS_MAX_SOURCES];
+spinlock_t linuxpps_lock = SPIN_LOCK_UNLOCKED;
/* --- Local variables ----------------------------------------------------- */
diff --git a/include/linux/pps.h b/include/linux/pps.h
index 8965c29..5302e39 100644
--- a/include/linux/pps.h
+++ b/include/linux/pps.h
@@ -72,13 +72,25 @@ struct linuxpps_s {
/* --- Global variables ---------------------------------------------------- */
extern struct linuxpps_s linuxpps_source[LINUXPPS_MAX_SOURCES];
+extern spinlock_t linuxpps_lock;
/* --- Global functions ---------------------------------------------------- */
-static inline int linuxpps_is_allocated(int source) {
+static inline int __linuxpps_is_allocated(int source) {
return linuxpps_source[source].info != NULL;
}
+static inline int linuxpps_is_allocated(int source) {
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&linuxpps_lock, flags);
+ ret = __linuxpps_is_allocated(source);
+ spin_unlock_irqrestore(&linuxpps_lock, flags);
+
+ return ret;
+}
+
/* --- Exported functions -------------------------------------------------- */
extern int linuxpps_register_source(struct linuxpps_source_info_s *info, int default_params, int try_id);
More information about the LinuxPPS
mailing list