Index: trunk/kernel/kern/thread.h
===================================================================
--- trunk/kernel/kern/thread.h	(revision 406)
+++ trunk/kernel/kern/thread.h	(revision 407)
@@ -27,4 +27,5 @@
 
 #include <hal_types.h>
+#include <shared_syscalls.h>
 #include <hal_special.h>
 #include <xlist.h>
@@ -51,31 +52,4 @@
 
 /***************************************************************************************
- * This defines the various pthread_attr_t attributes bit-vector.
- **************************************************************************************/
-
-/***************************************************************************************
- * This opaque structure contains the user defined attributes for a user thread.
- * It is passed as input argument to the thread_user_create() function.
- * It is set by the user application itself, using the pthread_attr_***() functions.
- * The currently supported attributes are defined below.
- **************************************************************************************/
-
-typedef struct pthread_attr_s
-{
-	uint32_t    attributes;      /*! user defined attributes bit vector               */
-	cxy_t       cxy;             /*! target cluster identifier                        */
-	lid_t       lid;             /*! target core index                                */
-}
-pthread_attr_t;
-
-typedef enum
-{
-    PT_ATTR_DETACH          = 0x0001,  /*! user defined not joinable                  */
-    PT_ATTR_CLUSTER_DEFINED = 0x0002,  /*! user defined target cluster                */
-    PT_ATTR_CORE_DEFINED    = 0x0004,  /*! user defined core index in cluster         */
-}
-pt_attributes_t;
-
-/***************************************************************************************
  * This enum defines the thread types.
  **************************************************************************************/
@@ -86,7 +60,5 @@
 	THREAD_RPC     = 1,          /*! kernel thread executing pending RPCs             */
 	THREAD_DEV     = 2,          /*! kernel thread executing I/O device commands      */
-	THREAD_KERNEL  = 3,          /*! other kernel thread                              */
-	THREAD_IDLE    = 4,          /*! kernel idle thread                               */
-	THREAD_TYPES_NR
+	THREAD_IDLE    = 3,          /*! kernel idle thread                               */
 }
 thread_type_t;
@@ -100,5 +72,5 @@
 #define THREAD_FLAG_JOIN         0x0004  /*! Parent thread made a join                */
 #define THREAD_FLAG_EXIT         0x0008  /*! This thread made an exit                 */
-#define THREAD_FLAG_SCHED        0x0010  /*! Descheduling required for this thread    */
+#define THREAD_FLAG_SCHED        0x0010  /*! Scheduling required for this thread      */
 
 /***************************************************************************************
@@ -106,5 +78,6 @@
  **************************************************************************************/
 
-#define THREAD_SIG_KILL          0x0001  /*! This thread must be destroyed ASAP       */
+#define THREAD_SIG_KILL          0x0001  /*! This thread killed by another thread     */
+#define THREAD_SIG_SUICIDE       0x0002  /*! This thread required exit                */
 
 /***************************************************************************************
@@ -116,11 +89,11 @@
 #define THREAD_BLOCKED_MAPPER    0x0004  /*! thread wait mapper                       */
 #define THREAD_BLOCKED_JOIN      0x0008  /*! thread blocked in join / wait exit       */
-#define THREAD_BLOCKED_EXIT      0x0010  /*! thread blocked in exit / wait join i     */
+#define THREAD_BLOCKED_EXIT      0x0010  /*! thread blocked in exit / wait join       */
 #define THREAD_BLOCKED_KILL      0x0020  /*! thread received kill signal              */
 #define THREAD_BLOCKED_SEM       0x0040  /*! thread wait semaphore                    */
 #define THREAD_BLOCKED_PAGE      0x0080  /*! thread wait page access                  */
 #define THREAD_BLOCKED_USERSYNC  0x0100  /*! thread wait POSIX (cond/mutex/barrier)   */
-
-#define THREAD_BLOCKED_IDLE      0x1000  /*! thread RPC wait activation               */
+#define THREAD_BLOCKED_RPC       0x0200  /*! thread wait RPC completion               */
+
 #define THREAD_BLOCKED_DEV_QUEUE 0x2000  /*! thread DEV wait queue                    */
 #define THREAD_BLOCKED_DEV_ISR   0x4000  /*! thread DEV wait ISR                      */
@@ -199,6 +172,6 @@
 
     uint32_t            flags;           /*! bit vector of flags                      */
-    uint32_t            blocked;         /*! bit vector of blocking causes            */
-    uint32_t            signals;         /*! bit vector of signals                    */
+    volatile uint32_t   blocked;         /*! bit vector of blocking causes            */
+    volatile uint32_t   signals;         /*! bit vector of (KILL / SUICIDE) signals   */
 
 	error_t             errno;           /*! errno value set by last system call      */
@@ -212,5 +185,5 @@
     remote_spinlock_t * children_lock;   /*! lock protecting the children list        */
 
-    xlist_entry_t       brothers_list;   /*! member of threads with same parent       */
+    xlist_entry_t       brothers_list;   /*! list of attached threads to same parent  */
 
 	list_entry_t        sched_list;      /*! member of threads attached to same core  */
@@ -273,18 +246,27 @@
 
 /***************************************************************************************
- * This function allocates memory for an user thread descriptor in the local cluster,
+ * This function is used by the fork() system call to create the child process main 
+ * thread. It allocates memory for an user thread descriptor in the local cluster,
  * and initializes it from information contained in the calling thread descriptor.
- * It is used by the fork() system call to create the child process main thread.
- * The new thread is attached to the core with the lowest load.
- * It is registered in the process descriptor defined by the "process" argument.
- * This new thread inherits its execution context from the calling thread,
- * and the "loadable" field is NOT set.
- * The THREAD_BLOCKED_GLOBAL bit is set, and the thread must be activated to start.
+ * The new thread is attached to the core that has the lowest load in local cluster.
+ * It is registered in the child process descriptor defined by the <process> argument.
+ * This new thread inherits its user stack from the parent thread, as it uses the
+ * Copy-On-Write mechanism to get a private stack when required.
+ * The content of the parent kernel stack is copied into the child kernel stack, as 
+ * the Copy-On-Write mechanism cannot be used for kernel segments (because kernel 
+ * uses physical addressing on some architectures).
+ * The CPU and FPU execution contexts are created and linked to the new thread,
+ * but the actual context copy is NOT done. The THREAD_BLOCKED_GLOBAL bit is set,
+ * and the thread must be explicitely unblocked later to make the new thread runable.
  ***************************************************************************************
  * @ process      : local pointer on owner process descriptor.
+ * @ stack_base   : user stack base address (from parent).
+ * @ stack_size   : user stack size (from parent).
  * @ new_thread   : [out] address of buffer for new thread descriptor pointer.
  * @ returns 0 if success / returns ENOMEM if error.
  **************************************************************************************/
 error_t thread_user_fork( process_t * process,
+                          intptr_t    stack_base,
+                          uint32_t    stack_size,
                           thread_t ** new_thread );
 
@@ -351,9 +333,9 @@
  * It does NOT take a lock, as this function is always called by the parent thread.
  ***************************************************************************************
- * @ xp_parent : extended pointer on the parent thread descriptor.
- * @ xp_child  : extended pointer on the child thread descriptor.
- **************************************************************************************/
-void thread_child_parent_link( xptr_t  xp_parent,
-                               xptr_t  xp_child );
+ * @ parent_xp : extended pointer on the parent thread descriptor.
+ * @ child_xp  : extended pointer on the child thread descriptor.
+ **************************************************************************************/
+void thread_child_parent_link( xptr_t  parent_xp,
+                               xptr_t  child_xp );
 
 /***************************************************************************************
@@ -361,9 +343,9 @@
  * of attached children threads.
  ***************************************************************************************
- * @ xp_parent : extended pointer on the parent thread descriptor.
- * @ xp_child  : extended pointer on the child thread descriptor.
- **************************************************************************************/
-void thread_child_parent_unlink( xptr_t xp_parent,
-                                 xptr_t xp_child );
+ * @ parent_xp : extended pointer on the parent thread descriptor.
+ * @ child_xp  : extended pointer on the child thread descriptor.
+ **************************************************************************************/
+void thread_child_parent_unlink( xptr_t parent_xp,
+                                 xptr_t child_xp );
 
 /***************************************************************************************
@@ -386,14 +368,4 @@
 
 /***************************************************************************************
- * This function returns true if the calling thread is attached to its parent thread.
- **************************************************************************************/
-inline bool_t thread_is_joinable();
-
-/***************************************************************************************
- * This function returns true if the calling thread is not blocked.
- **************************************************************************************/
-inline bool_t thread_is_runnable();
-
-/***************************************************************************************
  * This function checks if the calling thread can deschedule.
  ***************************************************************************************
@@ -403,19 +375,24 @@
 
 /***************************************************************************************
- * This function implements the delayed descheduling machanism : It is called  by 
+ * This function implements the delayed descheduling mechanism : It is called  by 
  * all lock release functions, and calls the sched_yield() function when all locks 
- * have beeen released and the THREAD_FLAG_SCHED flag is set. 
+ * have beeen released and the calling thread THREAD_FLAG_SCHED flag is set. 
  **************************************************************************************/
 void thread_check_sched();
 
 /***************************************************************************************
- * This function can be used by the calling thread to suicide.
- * All locks must be previously released.
- * The scenario depends on the attached/detached flag :
- * - if detached, it sets the SIG_KILL signal in the "signals" bit_vector, registers
- *   the BLOCKED_EXIT bit in the "blocked" bit_vector, and deschedule.
- * - if attached, it simply sets the BLOCKED_EXIT bit in the "blocked" bit vector
- *   and deschedule. The SIG_KILL signal will be set by the parent thread when
- *   executing the pthread_join().
+ * This function is used by the calling thread to suicide.
+ * All locks must be previously released. The scenario depends on the DETACHED flag.
+ * if detached :
+ * 1) the calling thread sets the SIG_SUICIDE bit in the "signals" bit_vector,
+ *    registers the BLOCKED_GLOBAL bit in the "blocked" bit_vector, and deschedule.
+ * 2) the scheduler, detecting the SIG_SUICIDE bit, remove the thread from the
+ *    scheduler list, remove the thread from its process, and destroys the thread.
+ * if attached :
+ * 1) the calling thread simply sets the BLOCKED_EXIT bit in the "blocked" bit vector
+ *    and deschedule. 
+ * 2) The SIG_KILL bit and BLOCKED_SIGNAL bits are set by the parent thread when
+ *    executing the pthread_join(), and detecting the BLOCKED_EXIT bit.
+ *    The scenario is a standard kill as described below.
  ***************************************************************************************
  * @ returns 0 if success / returns EINVAL if locks_count is not zero.
@@ -424,9 +401,27 @@
 
 /***************************************************************************************
+ * This function request to kill a local target thread, with the following scenario:
+ * 1. This function set the BLOCKED_GLOBAL bit in target thread "blocked" bit_vector,
+ *    set the SIG_KILL bit in target thread "signals" bit_vector, and send an IPI
+ *    to the target thread core to force scheduling.
+ * 2. The scheduler, detecting the SIG_KILL set, removes the thread from the scheduler
+ *    list, and reset the SIG_KILL bit to acknowledge the killer.
+ * 3. The caller of this function, (such as the process_kill() function), must poll
+ *    SIG_KILL bit until reset, detach the thread from its parent if the thread is
+ *    attached, remove the thread from its process, and destroys the thread.
+ * 
+ * NOTE: The third step must be done by the caller to allows the process_kill()
+ *       function to parallelize the work on all schedulers in a given cluster.
+ ***************************************************************************************
+ * @ thread   : local pointer on the target thread.
+ **************************************************************************************/
+void thread_kill( thread_t * thread );
+
+/***************************************************************************************
  * This function registers a blocking cause in the target thread "blocked" bit vector.
- * Warning : this function does not deschedule the calling thread.
- * The descheduling can be forced by a sched_yield().
- ***************************************************************************************
- * @ thread   : local pointer on target thread.
+ * Warning : this function does not deschedule the calling thread, and the descheduling
+ * must be explicitely forced by a sched_yield().
+ ***************************************************************************************
+ * @ thread   : local pointer on target thread descriptor.
  * @ cause    : mask defining the cause (one hot).
  **************************************************************************************/
@@ -436,5 +431,5 @@
 /***************************************************************************************
  * This function resets the bit identified by the cause argument in the "blocked"
- * bit vector of a remote thread descriptor.
+ * bit vector of a remote thread descriptor, using an atomic access.
  * We need an extended pointer, because the client thread of an I/O operation on a
  * given device is not in the same cluster as the associated device descriptor.
@@ -444,19 +439,8 @@
  * @ thread   : extended pointer on the remote thread.
  * @ cause    : mask defining the cause (one hot).
- **************************************************************************************/
-void thread_unblock( xptr_t   thread,
-                     uint32_t cause );
-
-/***************************************************************************************
- * This function kills a target thread, identified by its local pointer.
- * It is generally called by the local process_destroy() function.
- * - it forces the global blocked bit in target thread descriptor.
- * - it set the SIG_KILL signal in target thread.
- * - it send an IPI_SCHED_REQUEST to the target thread core.
- ***************************************************************************************
- * @ thread   : local pointer on the target thread.
- * @ returns 0 if success / returns EINVAL if locks_count is not zero.
- **************************************************************************************/
-void thread_kill( thread_t * thread );
+ * @ return non zero if the bit-vector was actually modified / return 0 otherwise
+ **************************************************************************************/
+uint32_t thread_unblock( xptr_t   thread,
+                         uint32_t cause );
 
 /***************************************************************************************
