[LinuxPPS] Locking code

Rodolfo Giometti giometti at enneenne.com
Sun Nov 26 22:57:11 CET 2006


Hello,

I just published new code with locking code. After that we should be
ready to submit LinuxPPS to linux kernel main tree.

Please take a look at the patch (attached) and try the new code. In
order to do it you may update your git repository or just download the
new ntp-pps-2.6.19-rc2.diff patch from my site.

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..cbe1c36 100644
--- a/drivers/pps/kapi.c
+++ b/drivers/pps/kapi.c
@@ -48,7 +48,7 @@ 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;
 
@@ -97,7 +97,19 @@ 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;
 
@@ -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..12e311f 100644
--- a/include/linux/pps.h
+++ b/include/linux/pps.h
@@ -72,11 +72,19 @@ 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) {
-	return linuxpps_source[source].info != NULL;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&linuxpps_lock, flags);
+	ret = linuxpps_source[source].info != NULL;
+	spin_unlock_irqrestore(&linuxpps_lock, flags);
+
+	return ret;
 }
 
 /* --- Exported functions -------------------------------------------------- */


More information about the LinuxPPS mailing list