Index: trunk/kernel/kern/alarm.c
===================================================================
--- trunk/kernel/kern/alarm.c	(revision 494)
+++ trunk/kernel/kern/alarm.c	(revision 669)
@@ -1,15 +1,16 @@
 /*
- * kern/time.c - thread time related management
- * 
- * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
- * Copyright (c) 2011,2012 UPMC Sorbonne Universites
+ * alarm.c - timer based kernel alarm implementation            
  *
- * This file is part of ALMOS-kernel.
+ * Author     Alain Greiner (2016,2017,2018,2019,2020)
  *
- * ALMOS-kernel is free software; you can redistribute it and/or modify it
+ * Copyright (c) UPMC Sorbonne Universites
+ *
+ * This file is part of ALMOS-MKH.
+ *
+ * ALMOS-MKH is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by
  * the Free Software Foundation; version 2.0 of the License.
  *
- * ALMOS-kernel is distributed in the hope that it will be useful, but
+ * ALMOS-MKH is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
@@ -17,155 +18,153 @@
  *
  * You should have received a copy of the GNU General Public License
- * along with ALMOS-kernel; if not, write to the Free Software Foundation,
+ * along with ALMOS-MKH; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include <types.h>
+#include <kernel_config.h>
+#include <hal_kernel_types.h>
+#include <printk.h>
+#include <list.h>
 #include <thread.h>
-#include <task.h>
-#include <scheduler.h>
-#include <time.h>
-#include <list.h>
-#include <rt_timer.h>
-#include <kmagics.h>
+#include <core.h>
+#include <alarm.h>
 
-error_t alarm_wait(struct alarm_info_s *info, uint_t msec)
+////////////////////////////////////////////////////////////////////////////////////////////
+// This static function registers the alarm identified ny the <new_alarm> argument 
+// in the list of alarms rooted in the core identified by the <core> argument.
+// When the existing list of alarms is not empty, it scan the list to insert the new
+// alarm in the right place to respect the absolute dates ordering. 
+////////////////////////////////////////////////////////////////////////////////////////////
+// @ new_alarm  : local pointer on the new alarm.
+// @ core       : local pointer on the target core.
+////////////////////////////////////////////////////////////////////////////////////////////
+static void alarm_register( alarm_t * new_alarm,
+                            core_t  * core )
 {
-	register uint_t tm_now;
-	struct cpu_s *cpu;
-	struct alarm_s *alarm_mgr;
-	struct list_entry *iter;
-	struct alarm_info_s *current;
-	uint_t irq_state;
+    list_entry_t * current;          // pointer on current list_entry in existing list
+    list_entry_t * previous;         // pointer on previous list_entry in existing list
+    alarm_t      * current_alarm;    // pointer on current alarm in existing list
+    cycle_t        current_date;     // date of current alarm in existing list
 
-	cpu       = current_cpu;
-	alarm_mgr = &cpu->alarm_mgr;
+    bool_t         done = false;
 
-	cpu_disable_all_irq(&irq_state);
+    // get pointers on root of alarms and lock
+    list_entry_t * root = &core->alarms_root;
+    busylock_t   * lock = &core->alarms_lock;
 
-	tm_now          = cpu_get_ticks(cpu) * MSEC_PER_TICK;
-	info->signature = ALRM_INFO_ID;
-	info->tm_wakeup = tm_now + msec;
+    // get pointer on new_alarm list_entry 
+    list_entry_t * new_entry = &new_alarm->list;
 
-	if(list_empty(&alarm_mgr->wait_queue))
-		list_add_first(&alarm_mgr->wait_queue, &info->list);
-	else
-	{
-		list_foreach_forward(&alarm_mgr->wait_queue, iter)
-		{
-			current = list_element(iter, struct alarm_info_s, list);
-      
-			if(info->tm_wakeup <= current->tm_wakeup) 
-			{
-				list_add_pred(iter, &info->list);
-				goto NEXT_TRAITMENT;
-			}
-		}
-		list_add_last(&alarm_mgr->wait_queue, &info->list);
-	}
+    // get new_alarm date
+    cycle_t        new_date = new_alarm->date;
 
-NEXT_TRAITMENT:
-	cpu_restore_irq(irq_state);
-	return 0;
-}
+    // take the lock
+    busylock_acquire( lock );
 
-void alarm_clock(struct alarm_s *alarm, uint_t ticks_nr)
+    // insert new alarm to respect dates order
+    if( list_is_empty( root ) )                     // list empty
+    {
+        list_add_first( root , new_entry ); 
+    }
+    else                                            // list non empty
+    {
+        for( current = root->next ;
+             (current != root) && (done == false) ;
+             current = current->next )
+        {
+            // get pointer on previous entry in existing list
+            previous = current->pred;
+
+            // get pointer on current alarm 
+            current_alarm = LIST_ELEMENT( current , alarm_t , list );
+
+            // get date for current alarm 
+            current_date  = current_alarm->date;
+
+            if( current_date > new_date )  // insert new alarm just before current
+            {
+                new_entry->next = current;
+                new_entry->pred = previous;
+
+                current->pred  = new_entry;
+                previous->next = new_entry;
+                
+                done = true;
+            }
+        }  // end for
+        
+        if( done == false ) // new_date is larger than all registered dates
+        {
+            list_add_last( root , new_entry );
+        }
+    }
+
+    // release the lock
+    busylock_release( lock );
+
+}  // end alarm_register()
+
+//////////////////////////////////////
+void alarm_start( cycle_t    date,
+                  void     * func_ptr,
+                  xptr_t     args_xp,
+                  thread_t * thread )
 {
-	register uint_t tm_msec;
-	register struct list_entry *iter;
-	register struct alarm_info_s *info;
-  
-	tm_msec = ticks_nr * MSEC_PER_TICK;
+    // get pointer on alarm
+    alarm_t * alarm = &thread->alarm;
 
-	list_foreach_forward(&alarm->wait_queue, iter)
-	{
-		info = list_element(iter, struct alarm_info_s, list);
+    // initialize alarm descriptor
+    alarm->date     = date;
+    alarm->func_ptr = func_ptr;
+    alarm->args_xp = args_xp;
+    
+    // register alarm in core list
+    alarm_register( alarm , thread->core );
 
-		assert((info->signature == ALRM_INFO_ID), "Not an ALRM info object");
+}  // end alarm_start()
 
-		if(tm_msec < info->tm_wakeup)
-			break;
+/////////////////////////////////////
+void alarm_update( thread_t * thread,
+                   cycle_t    new_date )
+{
+    // get pointer on alarm
+    alarm_t * alarm = &thread->alarm;
+
+    // get pointer on core 
+    core_t   * core = thread->core;
+
+    // get pointer on lock protecting the alarms list
+    busylock_t   * lock = &core->alarms_lock;
+
+    // unlink the alarm from the core list
+    busylock_acquire( lock );
+    list_unlink( &alarm->list );
+    busylock_release( lock );
+
+    // update the alarm date
+    alarm->date = new_date;
+
+    // register alarm in core list
+    alarm_register( alarm , core );
     
-		list_unlink(iter);
-		event_send(info->event, current_cpu->gid);
-	}
-}
+}  // end alarm_update()
 
-error_t alarm_manager_init(struct alarm_s *alarm)
+////////////////////////////////////
+void alarm_stop( thread_t * thread )
 {
-	list_root_init(&alarm->wait_queue);
-	return 0;
-}
+    // get pointer on alarm
+    alarm_t * alarm = &thread->alarm;
 
+    // get pointer on core 
+    core_t * core = thread->core;
 
-#if CONFIG_THREAD_TIME_STAT
+    // get pointer on lock protecting the alarms list
+    busylock_t * lock = &core->alarms_lock;
 
-inline void tm_sleep_compute(struct thread_s *thread)
-{
-	uint_t tm_now;
+    // unlink the alarm from the list rooted in core
+    busylock_acquire( lock );
+    list_unlink( &alarm->list );
+    busylock_release( lock );
 
-	if(thread->type == TH_IDLE)
-		return;
+}  // end alarm_stop()
 
-	rt_timer_read(&tm_now);
-	thread->info.tm_sleep += (tm_now - thread->info.tm_tmp);
-	thread->info.tm_tmp    = tm_now;
-}
-
-inline void tm_usr_compute(struct thread_s *thread)
-{ 
-	uint_t tm_now;
-
-	rt_timer_read(&tm_now);
-	thread->info.tm_usr += (tm_now - thread->info.tm_tmp);
-	thread->info.tm_tmp  = tm_now;
-}
-
-inline void tm_sys_compute(struct thread_s *thread)
-{ 
-	uint_t tm_now;
-
-	rt_timer_read(&tm_now);
-	thread->info.tm_sys += (tm_now - thread->info.tm_tmp);
-	thread->info.tm_tmp  = tm_now;
-}
-
-inline void tm_wait_compute(struct thread_s *thread)
-{
-	uint_t tm_now;
-
-	if(thread->type == TH_IDLE)
-		return;
-
-	rt_timer_read(&tm_now);
-	thread->info.tm_wait += (tm_now - thread->info.tm_tmp);
-	thread->info.tm_tmp   = tm_now;
-	thread->info.tm_exec  = tm_now;
-}
-
-inline void tm_exit_compute(struct thread_s *thread)
-{
-	uint_t tm_now;
-  
-	rt_timer_read(&tm_now);
-	thread->info.tm_sys += tm_now - thread->info.tm_tmp;
-	thread->info.tm_dead = tm_now;
-}
-
-inline void tm_born_compute(struct thread_s *thread)
-{
-	uint_t tm_now;
-  
-	rt_timer_read(&tm_now);
-	thread->info.tm_born = tm_now;
-	thread->info.tm_tmp  = tm_now;
-	thread->info.tm_exec = tm_now;
-}
-
-inline void tm_create_compute(struct thread_s *thread)
-{
-	rt_timer_read(&thread->info.tm_create);
-}
-
-
-#endif	/* CONFIG_THREAD_TIME_STAT */
