Latest working version.. tested with david's latest code
authorAkshay Giridhar <akshay87@vt.edu>
Wed, 10 Sep 2014 20:56:31 +0000 (16:56 -0400)
committerAkshay Giridhar <akshay87@vt.edu>
Wed, 10 Sep 2014 20:56:31 +0000 (16:56 -0400)
29 files changed:
arch/x86/kernel/cpu/proc.c
arch/x86/kernel/entry_64.S
arch/x86/kernel/process.c
arch/x86/kernel/process_64.c
arch/x86/kernel/smpboot.c
arch/x86/mm/fault.c
fs/binfmt_elf.c
fs/exec.c
fs/proc/meminfo.c
include/linux/multikernel.h
include/linux/pcn_kmsg.h
include/linux/process_server.h
include/linux/sched.h
include/linux/syscalls.h
include/popcorn/global_spinlock.h
include/popcorn/init.h
include/popcorn/request_data.h
kernel/exit.c
kernel/futex.c
kernel/futex_remote.c
kernel/global_spinlock.c
kernel/kinit.c
kernel/process_server.c
kernel/sched.c
kernel/signal.c
mm/mprotect.c
mm/mremap.c
pcnmsg/pcn_kmsg.c
pcnmsg/pcn_kmsg_test.c

index 125a894..3b8a0ab 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/string.h>
 #include <linux/seq_file.h>
 #include <linux/cpufreq.h>
+#include <linux/multikernel.h>
 
 /*mklinux_akshay*/
 extern int remote_proc_cpu_info(struct seq_file *m);
@@ -145,7 +146,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 
        //append remote cpu info
        /*mklinux_akshay*/
-       remote_proc_cpu_info(m);
+       if(popcorn_boot == 1)
+               remote_proc_cpu_info(m);
        /*mklinux_akshay*/
        return 0;
 }
index dd1f182..f60a997 100644 (file)
@@ -1205,6 +1205,21 @@ ENTRY(kernel_execve)
        CFI_ENDPROC
 END(kernel_execve)
 
+ENTRY(kernel_import_task)
+        CFI_STARTPROC
+        FAKE_STACK_FRAME $0
+        SAVE_ALL
+        movq %rsp,%rcx
+        call sys_process_server_import_task
+        movq %rax, RAX(%rsp)
+        RESTORE_REST
+        testq %rax,%rax
+        je int_ret_from_sys_call
+        RESTORE_ARGS
+        UNFAKE_STACK_FRAME
+        ret
+        CFI_ENDPROC
+END(kernel_import_task)
 /* Call softirq on interrupt stack. Interrupts are off. */
 ENTRY(call_softirq)
        CFI_STARTPROC
index 5417dca..e628391 100644 (file)
@@ -316,8 +316,10 @@ long sys_execve(const char __user *name,
                return error;
        error = do_execve(filename, argv, envp, regs);
 
-       if(error ==-2)
+/*     if(error ==-2)
         printk(KERN_ALERT "filename {%s} name {%s} error{%d}\n",filename,name,error);
+*
+*/
 #ifdef CONFIG_X86_32
        if (error == 0) {
                /* Make sure we don't return using sysenter.. */
index 125cf3d..a97143f 100644 (file)
@@ -368,6 +368,50 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
                            __USER_CS, __USER_DS, 0);
 }
 
+static bool __user_addr (unsigned long x ) {
+     return (x < PAGE_OFFSET);
+}
+
+void start_remote_thread(struct pt_regs *regs){
+     unsigned int fsindex, gsindex;
+     unsigned short es,ds;
+
+     savesegment(fs, fsindex);
+     if ( !(current->thread.fs) || !(__user_addr(current->thread.fs)) ) {
+        printk(KERN_ERR "%s: ERROR corrupted fs base address %lu\n", __func__, current->thread.fs);
+     }
+
+     if (unlikely(fsindex | current->thread.fsindex))
+        loadsegment(fs, current->thread.fsindex);
+     else
+         loadsegment(fs, 0);
+     if (current->thread.fs)
+         checking_wrmsrl(MSR_FS_BASE, current->thread.fs);
+
+    savesegment(gs, gsindex); //read the gs register in gsindex variable
+     if ( !(current->thread.gs) && !(__user_addr(current->thread.gs)) ) {
+         printk(KERN_ERR "%s: ERROR corrupted gs base address %lu\n", __func__, current->thread.gs);
+     }
+
+     if (unlikely(gsindex | current->thread.gsindex))
+         load_gs_index(current->thread.gsindex);
+     else
+         load_gs_index(0);
+     if (current->thread.gs)
+         checking_wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs);
+
+     savesegment(es, es);
+     if (unlikely(es | current->thread.es))
+         loadsegment(es, current->thread.es);
+
+     savesegment(ds, ds);
+     if (unlikely(ds | current->thread.ds))
+         loadsegment(ds, current->thread.ds);
+     percpu_write(old_rsp, current->thread.usersp);
+     regs->sp = current->thread.usersp;
+     free_thread_xstate(current);
+
+}
 #ifdef CONFIG_IA32_EMULATION
 void start_thread_ia32(struct pt_regs *regs, u32 new_ip, u32 new_sp)
 {
index d03e97e..38f2b33 100644 (file)
@@ -1266,9 +1266,13 @@ early_param("possible_cpus", _setup_possible_cpus);
 static DECLARE_BITMAP(setup_present_bits, CONFIG_NR_CPUS) __read_mostly;
 const struct cpumask *const setup_present_mask = to_cpumask(setup_present_bits);
 
+int popcorn_boot = 0;
+EXPORT_SYMBOL(popcorn_boot);
+
 static int __init _setup_present_mask(char *str)
 {
        cpulist_parse(str, (struct cpumask *)setup_present_mask);
+       popcorn_boot = 1;
        return 0;
 }
 early_param("present_mask", _setup_present_mask);
index 18099b4..eea9280 100644 (file)
@@ -709,7 +709,7 @@ static void
 __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
                       unsigned long address, int si_code)
 {
-       struct task_struct *tsk = current;
+       struct task_struct *tsk =(current->surrogate == -1) ? current : pid_task(find_get_pid(current->surrogate),PIDTYPE_PID);
 
        /* User mode accesses just cause a SIGSEGV */
        if (error_code & PF_USER) {
@@ -770,14 +770,24 @@ static void
 __bad_area(struct pt_regs *regs, unsigned long error_code,
           unsigned long address, int si_code)
 {
-       struct mm_struct *mm = current->mm;
+       struct task_struct *tsk =(current->surrogate == -1) ? current : pid_task(find_get_pid(current->surrogate),PIDTYPE_PID);
+       struct mm_struct *mm = tsk->mm;
 
        /*
         * Something tried to access memory that isn't in our memory map..
         * Fix it, but check if it's kernel or user first..
         */
+       if(1) //tsk->tgroup_distributed)
+       {       
+               if(mm->mmap_sem.count == 0){
+                   printk(KERN_ALERT"%s: no count\n",__func__); 
+                  goto p;
+               }
+               else
+                printk(KERN_ALERT"%s: count{%d} \n",__func__,mm->mmap_sem.count);
+       }
        up_read(&mm->mmap_sem);
-
+p:
        __bad_area_nosemaphore(regs, error_code, address, si_code);
 }
 
@@ -1005,7 +1015,7 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
     int original_enable_do_mmap_pgoff_hook = current->enable_do_mmap_pgoff_hook;
     int original_enable_distributed_munmap = current->enable_distributed_munmap;
 
-       tsk = current;
+       tsk =(current->surrogate == -1) ? current : pid_task(find_get_pid(current->surrogate),PIDTYPE_PID);
        mm = tsk->mm;
 
        /* Get the faulting address: */
index 5af0a72..e70b487 100644 (file)
@@ -991,16 +991,16 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
     /*
      * Multikernel
      */
+#ifdef PROCESS_SERVER_USE_KMOD
     if(current->executing_for_remote) {
         process_server_import_address_space(&mk_ip, &mk_sp, regs);
-        /*printk("stack pointer = %lx\n",mk_sp);
-        for(i = 0; i <= 16; i++) {
-            printk("stack peak %lx at %lx\n",*(unsigned long*)(mk_sp + i*8), mk_sp + i*8);
-        }*/
            start_thread(regs, mk_ip, mk_sp);
     } else {
         start_thread(regs, elf_entry, bprm->p);
     }
+#else
+    start_thread(regs, elf_entry, bprm->p);
+#endif
        retval = 0;
 out:
        kfree(loc);
@@ -1969,7 +1969,7 @@ static int elf_core_dump(struct coredump_params *cprm)
                size_t sz = get_note_info_size(&info);
 
                sz += elf_coredump_extra_notes_size();
-               printk(KERN_ALERT " phdr4note \n");
+
                phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL);
                if (!phdr4note)
                        goto end_coredump;
@@ -1986,7 +1986,6 @@ static int elf_core_dump(struct coredump_params *cprm)
 
        if (e_phnum == PN_XNUM) {
                shdr4extnum = kmalloc(sizeof(*shdr4extnum), GFP_KERNEL);
-               printk(KERN_ALERT " shdr4extnum \n");
                if (!shdr4extnum)
                        goto end_coredump;
                fill_extnum_info(elf, shdr4extnum, e_shoff, segs);
@@ -1995,12 +1994,10 @@ static int elf_core_dump(struct coredump_params *cprm)
        offset = dataoff;
 
        size += sizeof(*elf);
-       printk(KERN_ALERT " binfmt elf size{%d} \n",size);
        if (size > cprm->limit || !dump_write(cprm->file, elf, sizeof(*elf)))
                goto end_coredump;
 
        size += sizeof(*phdr4note);
-       printk(KERN_ALERT " phdr4note elf size{%d} \n",size);
        if (size > cprm->limit
            || !dump_write(cprm->file, phdr4note, sizeof(*phdr4note)))
                goto end_coredump;
@@ -2029,17 +2026,17 @@ static int elf_core_dump(struct coredump_params *cprm)
                    || !dump_write(cprm->file, &phdr, sizeof(phdr)))
                        goto end_coredump;
        }
-       printk(KERN_ALERT " after vma size{%d} \n",size);
+
        if (!elf_core_write_extra_phdrs(cprm->file, offset, &size, cprm->limit))
                goto end_coredump;
-       printk(KERN_ALERT " write_note_info\n");
+
        /* write out the notes section */
        if (!write_note_info(&info, cprm->file, &foffset))
                goto end_coredump;
-       printk(KERN_ALERT " elf_coredump_extra_notes_write\n");
+
        if (elf_coredump_extra_notes_write(cprm->file, &foffset))
                goto end_coredump;
-       printk(KERN_ALERT " dump_seek\n");
+
        /* Align to page */
        if (!dump_seek(cprm->file, dataoff - foffset))
                goto end_coredump;
@@ -2069,10 +2066,10 @@ static int elf_core_dump(struct coredump_params *cprm)
                                goto end_coredump;
                }
        }
-       printk(KERN_ALERT " elf_core_write_extra_data\n");
+
        if (!elf_core_write_extra_data(cprm->file, &size, cprm->limit))
                goto end_coredump;
-       printk(KERN_ALERT " PN_XNUM\n");
+
        if (e_phnum == PN_XNUM) {
                size += sizeof(*shdr4extnum);
                if (size > cprm->limit
index 0bbec73..da93725 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -813,7 +813,7 @@ int kernel_read(struct file *file, loff_t offset,
 
 EXPORT_SYMBOL(kernel_read);
 
-static int exec_mmap(struct mm_struct *mm)
+int exec_mmap(struct mm_struct *mm)
 {
        struct task_struct *tsk;
        struct mm_struct * old_mm, *active_mm;
@@ -1011,7 +1011,7 @@ no_thread_group:
  * These functions flushes out all traces of the currently running executable
  * so that a new one can be started
  */
-static void flush_old_files(struct files_struct * files)
+/*static*/ void flush_old_files(struct files_struct * files)
 {
        long j = -1;
        struct fdtable *fdt;
index 1f4ff74..df1d0f0 100644 (file)
@@ -176,16 +176,6 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
 
        arch_report_meminfo(m);
 
-       /*mklinux_akshay*/
-       struct task_struct *t;
-       t=current;
-       int o;
-       printk("show: current comm: %s   pid:%d-%d",t->comm,strlen(t->comm),strlen("cat"));
-       if(!(o=strcmp (t->comm,"cat")))
-               remote_proc_meminfo_info(m);
-
-
-       printk("show: O: %d",o);/*mklinux_akshay*/
        return 0;
 #undef K
 }
index 24f7b07..6c96267 100644 (file)
@@ -8,6 +8,7 @@
 
 #define POPCORN_MAX_CPUS 64
 
+extern int popcorn_boot;
 extern int mklinux_boot;
 
 #endif /* __LINUX_MULTIKERNEL_H */
index 12c79bd..32a8271 100644 (file)
@@ -113,7 +113,18 @@ enum pcn_kmsg_type {
        PCN_KMSG_TYPE_PROC_SRV_MUNMAP_REQUEST,
        PCN_KMSG_TYPE_PROC_SRV_MUNMAP_RESPONSE,
     PCN_KMSG_TYPE_PROC_SRV_BACK_MIGRATION,
-       PCN_KMSG_TYPE_PCN_PERF_START_MESSAGE,
+    PCN_KMSG_TYPE_PROC_SRV_LAMPORT_BARRIER_REQUEST,
+    PCN_KMSG_TYPE_PROC_SRV_LAMPORT_BARRIER_REQUEST_RANGE,
+    PCN_KMSG_TYPE_PROC_SRV_LAMPORT_BARRIER_RESPONSE,
+    PCN_KMSG_TYPE_PROC_SRV_LAMPORT_BARRIER_RESPONSE_RANGE,
+    PCN_KMSG_TYPE_PROC_SRV_LAMPORT_BARRIER_RELEASE,
+    PCN_KMSG_TYPE_PROC_SRV_LAMPORT_BARRIER_RELEASE_RANGE,
+    PCN_KMSG_TYPE_PROC_SRV_GET_COUNTER_PHYS_REQUEST,
+    PCN_KMSG_TYPE_PROC_SRV_GET_COUNTER_PHYS_RESPONSE,
+    PCN_KMSG_TYPE_PROC_SRV_STATS_CLEAR,
+    PCN_KMSG_TYPE_PROC_SRV_STATS_QUERY,   
+    PCN_KMSG_TYPE_PROC_SRV_STATS_RESPONSE, 
+    PCN_KMSG_TYPE_PCN_PERF_START_MESSAGE,
        PCN_KMSG_TYPE_PCN_PERF_END_MESSAGE,
        PCN_KMSG_TYPE_PCN_PERF_CONTEXT_MESSAGE,
        PCN_KMSG_TYPE_PCN_PERF_ENTRY_MESSAGE,
index 8a09088..c22d799 100644 (file)
@@ -20,8 +20,8 @@
 #define PROCESS_SERVER_CLONE_FAIL 1
 
 //configuration
-#define SUPPORT_FOR_CLUSTERING
-//#undef SUPPORT_FOR_CLUSTERING
+//#define SUPPORT_FOR_CLUSTERING
+#undef SUPPORT_FOR_CLUSTERING
 
 //#define PROCESS_SERVER_USE_KMOD
 #undef PROCESS_SERVER_USE_KMOD
index bb63197..61aafda 100644 (file)
@@ -445,6 +445,7 @@ struct sighand_struct {
        wait_queue_head_t       signalfd_wqh;
 };
 
+
 struct pacct_struct {
        int                     ac_flag;
        long                    ac_exitcode;
@@ -1575,7 +1576,9 @@ struct task_struct {
     /*
      * Multikernel
      */
-    int represents_remote;      /* Is this a placeholder process? */
+    spinlock_t mig_lock;
+    volatile int migration_state;
+    volatile int represents_remote;      /* Is this a placeholder process? */
     int executing_for_remote;   /* Is this executing on behalf of another cpu? */
     int next_pid;             /* What is the pid on the remote cpu? */
     int prev_pid;
@@ -1602,8 +1605,9 @@ struct task_struct {
     unsigned long known_cpu_with_tgroup_mm; /* List of remote cpus that already have a mm for this tgroup  */
 
     int origin_pid;/*first thread id created in the originating kernel*/
-    //struct kernel_robust_list_head  *kernel_robust_list;
-   // int in_distributed_lock_state;
+    pid_t surrogate;
+    unsigned long uaddr;
+    int futex_state;
 
 };
 
@@ -2647,7 +2651,7 @@ static inline void set_task_cpu(struct task_struct *p, unsigned int cpu)
 
 extern long sched_setaffinity(pid_t pid, const struct cpumask *new_mask);
 extern long sched_getaffinity(pid_t pid, struct cpumask *mask);
-
+extern int shadow_return_check(struct task_struct *tsk);
 extern void normalize_rt_tasks(void);
 
 #ifdef CONFIG_CGROUP_SCHED
index 80b26ad..b127552 100644 (file)
@@ -830,6 +830,7 @@ asmlinkage long sys_syncfs(int fd);
 
 int kernel_execve(const char *filename, const char *const argv[], const char *const envp[]);
 
+int kernel_import_task(void* info);
 
 asmlinkage long sys_perf_event_open(
                struct perf_event_attr __user *attr_uptr,
index 5c5af3d..3805dd9 100644 (file)
@@ -17,7 +17,7 @@
 #define LOCK_STAT 
 //#undef LOCK_STAT
 #define sp_hashfn(uaddr, pid)      \
-         hash_long((unsigned long)uaddr + (unsigned long)pid, _SPIN_HASHBITS)
+       hash_long((unsigned long)uaddr + (unsigned long)pid, _SPIN_HASHBITS)
 
 
 struct futex_common_data{
@@ -48,19 +48,22 @@ typedef struct spin_key {
 
 struct local_request_queue {
        pid_t _pid;
+       unsigned long uaddr;
        unsigned long _request_id;//ticket number _pid has acquired
        unsigned int wake_st; //token status
        wait_queue_head_t _wq; //to wait until the server responds
        enum {
-                       DONE, IDLE, INPROG
+               DONE, IDLE, INPROG
        } status;
        int errno;
+       int ops;
+       int _st;
        struct list_head lrq_member;
 } __attribute__((packed));
 typedef struct local_request_queue _local_rq_t;
 
 struct global_request_queue {
-//     volatile struct plist_node list;
+       //      volatile struct plist_node list;
        _remote_wakeup_request_t wakeup;
        _remote_key_request_t wait;
        int cnt;
@@ -76,40 +79,54 @@ struct global_request_work  {
        struct work_struct work;
        spinlock_t * lock;
        _global_rq * gq;
-//     struct plist_head * _grq_head;
-//     volatile unsigned int _is_alive;
-//     pid_t _worker_pid;
-//     wait_queue_head_t *flush;
-//     unsigned int * free_work;
-//     int ops ; //0-wait 1-wake
+       //      struct plist_head * _grq_head;
+       //      volatile unsigned int _is_alive;
+       //      pid_t _worker_pid;
+       //      wait_queue_head_t *flush;
+       //      unsigned int * free_work;
+       //      int ops ; //0-wait 1-wake
 };
 
 typedef struct global_request_work global_request_work_t;
+struct migration_value{
+       pid_t pid;
+       unsigned long uaddr;
+       int ops;
+       struct timespec request_time;
+       volatile unsigned long served;
+       struct timespec response_time;
+};
+typedef struct migration_value  _mig_value;
 
 struct spin_value {
        spinlock_t _sp;
        volatile unsigned int _st; //token status//TBR
-       volatile unsigned int lock_st; // lock is global or local //TBR
        volatile unsigned long _ticket;
+       _mig_value *mig_st;
        struct list_head _lrq_head; //stores the status of ticket and wait queues
 };
 typedef struct spin_value  _spin_value;
 
 struct global_value {
-       spinlock_t lock;
-//     volatile struct plist_head _grq_head; // TODO for storing mutiple wq
+       //      volatile struct plist_head _grq_head; // TODO for storing mutiple wq
        struct workqueue_struct *global_wq;
        struct task_struct *thread_group_leader;
        global_request_work_t *worker_task;
        unsigned int free :1;
        char name[32];
+       struct list_head _link_head;
 };
 typedef struct global_value _global_value;
 
-
+struct global_value_bag{
+       spinlock_t lock;
+       struct list_head link;
+};
+typedef struct global_value_bag _global_bkt;
+       
 
 _spin_value *hashspinkey(_spin_key *sk);
-_global_value *hashgroup(struct task_struct *group_pid);
+_global_bkt *hashgroup(struct task_struct *group_pid);
 
 
 //Populate spin key from uaddr
@@ -124,9 +141,11 @@ int find_and_delete_request(int request_id, struct list_head *head);
 _local_rq_t * find_request(int request_id, struct list_head *head) ;
 _local_rq_t * find_request_by_pid(pid_t pid, struct list_head *head) ;
 _local_rq_t * set_err_request(int request_id,int err, struct list_head *head) ;
-
+int find_and_delete_pid(int pid, struct list_head *head);
+_local_rq_t *set_wake_request_by_pid(pid_t pid, struct list_head *head);
+_local_rq_t *find_request_by_ops(int ops, unsigned long uaddr, pid_t pid, struct list_head *head);
 
 extern _spin_value spin_bucket[1 << _SPIN_HASHBITS];
-extern _global_value global_bucket[1 << _SPIN_HASHBITS];
+extern _global_bkt global_bucket[1 << _SPIN_HASHBITS];
 
 #endif
index dc69802..07b2602 100644 (file)
@@ -19,9 +19,9 @@ extern int _init_RemoteCPUMask(void);
 
 extern struct list_head rlist_head;
 
-//extern struct list_head pfn_list_head;
+extern struct list_head pfn_list_head;
 
-//extern int _init_RemotePFN(void);
+extern int _init_RemotePFN(void);
 
 
 #endif /* __POPCORN_INIT_H */
index 95c1bec..c430a89 100644 (file)
@@ -17,7 +17,7 @@ struct _remote_wakeup_request {
        unsigned int ticket;    // 4
        unsigned long uaddr;    // 8
        unsigned long uaddr2;   // 8
-       unsigned int ops :1;    // 1
+       unsigned int ops:1;     // 1
        char pad[3];
 }__attribute__((packed)) __attribute__((aligned(64)));
 
@@ -50,7 +50,7 @@ struct _remote_key_request {
        int val;                                // 4
        int tghid;                              // 4
        unsigned int ticket;    // 4
-       unsigned int ops :1;    // 1
+       unsigned int ops :1;    // 4
        char pad_string[19];
 }__attribute__((packed)) __attribute__((aligned(64)));
 
index dc4dde1..0eeb479 100644 (file)
@@ -62,7 +62,7 @@
 #include "futex_remote.h"
 #include <popcorn/global_spinlock.h>
 
-static void exit_mm(struct task_struct * tsk);
+static void exit_mm(struct task_struct * tsk,long code);
 
 static void __unhash_process(struct task_struct *p, bool group_dead)
 {
@@ -426,7 +426,7 @@ void daemonize(const char *name, ...)
         * user space pages.  We don't need them, and if we didn't close them
         * they would be locked into memory.
         */
-       exit_mm(current);
+       exit_mm(current,0);
        /*
         * We don't want to have TIF_FREEZE set if the system-wide hibernation
         * or suspend transition begins right now.
@@ -638,7 +638,7 @@ assign_new_owner:
  * Turn us into a lazy TLB process if we
  * aren't already..
  */
-static void exit_mm(struct task_struct * tsk)
+static void exit_mm(struct task_struct * tsk,long code)
 {
        struct mm_struct *mm = tsk->mm;
        struct core_state *core_state;
@@ -991,6 +991,7 @@ NORET_TYPE void do_exit(long code)
     /*
      * Multikernel
      */
+       
     process_server_do_exit();
 #ifdef FUTEX_STAT
     if(current->tgroup_distributed && current->pid == current->tgroup_home_id){
@@ -1035,8 +1036,7 @@ NORET_TYPE void do_exit(long code)
        tsk->exit_code = code;
        taskstats_exit(tsk, group_dead);
        
-       if(tsk->mm!=NULL)
-            exit_mm(tsk);
+       exit_mm(tsk,code);
 
        if (group_dead)
                acct_process();
index 7a06fea..96663bb 100644 (file)
 #else
 #define FPRINTK(...) ;
 #endif
-
+#define WAIT_MAIN 99
 #define ENOTINKRN 999
 static void printPTE(u32 __user *uaddr);
 int __read_mostly futex_cmpxchg_enabled;
-
+static int _cpu=0;
 #define FUTEX_HASHBITS (CONFIG_BASE_SMALL ? 4 : 8)
 
 /*
@@ -121,9 +121,9 @@ struct futex_hash_bucket futex_queues[1<<FUTEX_HASHBITS];
 struct futex_hash_bucket *hash_futex(union futex_key *key)
 {
        u32 hash = jhash2((u32*)&key->both.word,
-                         (sizeof(key->both.word)+sizeof(key->both.ptr))/4,
-                        // (sizeof(key->both.word)+8)/4,
-                         key->both.offset);
+                       (sizeof(key->both.word)+sizeof(key->both.ptr))/4,
+                       // (sizeof(key->both.word)+8)/4,
+                       key->both.offset);
        return &futex_queues[hash & ((1 << FUTEX_HASHBITS)-1)];
 }
 
@@ -134,9 +134,9 @@ struct futex_hash_bucket *hash_futex(union futex_key *key)
 int match_futex(union futex_key *key1, union futex_key *key2)
 {
        return (key1 && key2
-               && key1->both.word == key2->both.word
-               && key1->both.ptr == key2->both.ptr
-               && key1->both.offset == key2->both.offset);
+                       && key1->both.word == key2->both.word
+                       && key1->both.ptr == key2->both.ptr
+                       && key1->both.offset == key2->both.offset);
 }
 
 /*
@@ -151,12 +151,12 @@ void get_futex_key_refs(union futex_key *key)
                return;
 
        switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) {
-       case FUT_OFF_INODE:
-               ihold(key->shared.inode);
-               break;
-       case FUT_OFF_MMSHARED:
-               atomic_inc(&key->private.mm->mm_count);
-               break;
+               case FUT_OFF_INODE:
+                       ihold(key->shared.inode);
+                       break;
+               case FUT_OFF_MMSHARED:
+                       atomic_inc(&key->private.mm->mm_count);
+                       break;
        }
 }
 
@@ -173,12 +173,12 @@ static void drop_futex_key_refs(union futex_key *key)
        }
 
        switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) {
-       case FUT_OFF_INODE:
-               iput(key->shared.inode);
-               break;
-       case FUT_OFF_MMSHARED:
-               mmdrop(key->private.mm);
-               break;
+               case FUT_OFF_INODE:
+                       iput(key->shared.inode);
+                       break;
+               case FUT_OFF_MMSHARED:
+                       mmdrop(key->private.mm);
+                       break;
        }
 }
 
@@ -200,7 +200,7 @@ static void drop_futex_key_refs(union futex_key *key)
  * lock_page() might sleep, the caller should not hold a spinlock.
  */
 //static
-int
+       int
 get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
 {
        unsigned long address = (unsigned long)uaddr;
@@ -376,14 +376,14 @@ int fault_in_user_writeable(u32 __user *uaddr)
 
        down_read(&mm->mmap_sem);
        ret = fixup_user_fault(current, mm, (unsigned long)uaddr,
-                              FAULT_FLAG_WRITE);
+                       FAULT_FLAG_WRITE);
        up_read(&mm->mmap_sem);
 
        return ret < 0 ? ret : 0;
 }
 
 //static
- int fault_in_user_writeable_task(u32 __user *uaddr,struct task_struct * tgid)
+int fault_in_user_writeable_task(u32 __user *uaddr,struct task_struct * tgid)
 {
        struct mm_struct *mm = tgid->mm;
        int ret;
@@ -400,7 +400,7 @@ int fault_in_user_writeable(u32 __user *uaddr)
  * Must be called with the hb lock held.
  */
 static struct futex_q *futex_top_waiter(struct futex_hash_bucket *hb,
-                                       union futex_key *key)
+               union futex_key *key)
 {
        struct futex_q *this;
 
@@ -412,7 +412,7 @@ static struct futex_q *futex_top_waiter(struct futex_hash_bucket *hb,
 }
 
 static int cmpxchg_futex_value_locked(u32 *curval, u32 __user *uaddr,
-                                     u32 uval, u32 newval)
+               u32 uval, u32 newval)
 {
        int ret;
 
@@ -576,7 +576,7 @@ void exit_pi_state_list(struct task_struct *curr)
        raw_spin_unlock_irq(&curr->pi_lock);
 }
 
-static int
+       static int
 lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
                union futex_key *key, struct futex_pi_state **ps)
 {
@@ -701,9 +701,9 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
  * The hb->lock and futex_key refs shall be held by the caller.
  */
 static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb,
-                               union futex_key *key,
-                               struct futex_pi_state **ps,
-                               struct task_struct *task, int set_waiters)
+               union futex_key *key,
+               struct futex_pi_state **ps,
+               struct task_struct *task, int set_waiters)
 {
        int lock_taken, ret, ownerdied = 0;
        u32 uval, newval, curval, vpid = task_pid_vnr(task);
@@ -777,26 +777,26 @@ retry:
 
        if (unlikely(ret)) {
                switch (ret) {
-               case -ESRCH:
-                       /*
-                        * No owner found for this futex. Check if the
-                        * OWNER_DIED bit is set to figure out whether
-                        * this is a robust futex or not.
-                        */
-                       if (get_futex_value_locked(&curval, uaddr))
-                               return -EFAULT;
+                       case -ESRCH:
+                               /*
+                                * No owner found for this futex. Check if the
+                                * OWNER_DIED bit is set to figure out whether
+                                * this is a robust futex or not.
+                                */
+                               if (get_futex_value_locked(&curval, uaddr))
+                                       return -EFAULT;
 
-                       /*
-                        * We simply start over in case of a robust
-                        * futex. The code above will take the futex
-                        * and return happy.
-                        */
-                       if (curval & FUTEX_OWNER_DIED) {
-                               ownerdied = 1;
-                               goto retry;
-                       }
-               default:
-                       break;
+                               /*
+                                * We simply start over in case of a robust
+                                * futex. The code above will take the futex
+                                * and return happy.
+                                */
+                               if (curval & FUTEX_OWNER_DIED) {
+                                       ownerdied = 1;
+                                       goto retry;
+                               }
+                       default:
+                               break;
                }
        }
 
@@ -815,25 +815,19 @@ void __unqueue_futex(struct futex_q *q)
 
        if (WARN_ON_SMP(!q->lock_ptr))
        {
-               FPRINTK(KERN_ALERT " lockptr null warning on smp \n ");
                return;
        }
        if(!spin_is_locked(q->lock_ptr))
        {
-               FPRINTK(KERN_ALERT " lockptr held warning on smp \n ");
                return;
        }
        if(WARN_ON(plist_node_empty(&q->list)))
        {
-               FPRINTK(KERN_ALERT " lockptr held warning on smp \n ");
                return;
        }
 
        hb = container_of(q->lock_ptr, struct futex_hash_bucket, lock);
-       if(&hb->chain!=NULL)
-       {       plist_del(&q->list, &hb->chain);}
-       else
-               printk(KERN_ALERT"hb-chain {%p}\n",&hb->chain);
+       plist_del(&q->list, &hb->chain);
 }
 
 /*
@@ -951,7 +945,7 @@ static int unlock_futex_pi(u32 __user *uaddr, u32 uval)
 /*
  * Express the locking dependencies for lockdep:
  */
-static inline void
+       static inline void
 double_lock_hb(struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2)
 {
        if (hb1 <= hb2) {
@@ -964,7 +958,7 @@ double_lock_hb(struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2)
        }
 }
 
-static inline void
+       static inline void
 double_unlock_hb(struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2)
 {
        spin_unlock(&hb1->lock);
@@ -974,10 +968,10 @@ double_unlock_hb(struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2)
 
 
 inline void __spin_key_init (struct spin_key *st) {
-       st->_tgid = 0;
-       st->_uaddr = 0;
-       st->offset = 0;
- }
+       st->_tgid = 0;
+       st->_uaddr = 0;
+       st->offset = 0;
+}
 /*
  * Try acquiring spin lock only if ret == 0
  */
@@ -1004,6 +998,10 @@ __acquires(&value->_sp)
        _local_rq_t *rq_ptr= add_request_node(localticket_value,current->pid,&value->_lrq_head);
        rq_ptr->_pid = current->pid;
        rq_ptr->status = INPROG;
+       rq_ptr->_st = 0;
+       rq_ptr->wake_st = 0;
+       rq_ptr->ops = 0;
+       rq_ptr->uaddr = uaddr;
 
        //populate the hb
        hb = hash_futex(&q->key);
@@ -1025,27 +1023,23 @@ __acquires(&value->_sp)
        smp_mb();
 
        if(ret){
-               y  = get_user(x,uaddr);
-               //printk(KERN_ALERT "%s: uadrr{%lx} ti{%lx} check if there is wake up {%d} - {%d} {%d} {%d} \n",__func__,uaddr,localticket_value,rq_ptr->wake_st,ret,x,y);
                if(rq_ptr->wake_st == 1) //no need to queue it.
                {
                        ret = 0;
                }
        }
        else if (!ret){
-               get_user(dval,uaddr);
-               FPRINTK(KERN_ALERT"%s: check if there is wake up on ret=0 {%d} davl{%d}  \n",__func__,rq_ptr->wake_st,ret,dval);
                if(rq_ptr->wake_st == 1)//no neew to queue
                {
                        ret = -EWOULDBLOCK;
                }
        }
-       find_and_delete_request(localticket_value, &value->_lrq_head);
+       //find_and_delete_request(localticket_value, &value->_lrq_head);
 
        return ret;
 }
 
-int
+       int
 get_futex_key_tsk(u32 __user *uaddr, int fshared, union futex_key *key, int rw, struct task_struct * _tsk)
 {
        unsigned long address = (unsigned long)uaddr;
@@ -1059,15 +1053,15 @@ get_futex_key_tsk(u32 __user *uaddr, int fshared, union futex_key *key, int rw,
         *               */
        key->both.offset = address % PAGE_SIZE;
        if (unlikely((address % sizeof(u32)) != 0))
-                       return -EINVAL;
-                       address -= key->both.offset;
+               return -EINVAL;
+       address -= key->both.offset;
        /*
-              * PROCESS_PRIVATE futexes are fast.
-              * As the mm cannot disappear under us and the 'key' only needs
-              * virtual address, we dont even have to find the underlying vma.
-              * Note : We do have to check 'uaddr' is a valid user address,
-              *        but access_ok() should be faster than find_vma()
-                                                      */
+        *       * PROCESS_PRIVATE futexes are fast.
+        *       * As the mm cannot disappear under us and the 'key' only needs
+        *       * virtual address, we dont even have to find the underlying vma.
+        *       * Note : We do have to check 'uaddr' is a valid user address,
+        *       *        but access_ok() should be faster than find_vma()
+        *                                               */
        if (!fshared) {
                if (unlikely(!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))))
                        return -EFAULT;
@@ -1099,6 +1093,8 @@ __acquires(&value->_sp)
        _local_rq_t *rq_ptr= add_request_node(localticket_value,current->pid,&value->_lrq_head);
        rq_ptr->_pid = current->pid;
        rq_ptr->status = INPROG;
+       rq_ptr->ops  = 1;
+       rq_ptr->uaddr = uaddr;
 
        futex_common_data_t data_;
 
@@ -1127,7 +1123,7 @@ __acquires(&value->_sp)
  * Wake up waiters matching bitset queued on this futex (uaddr).
  */
 //static
-int
+       int
 futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset,unsigned int fn_flags,struct task_struct *_tsk)
 {
 #ifdef FUTEX_STAT
@@ -1146,6 +1142,11 @@ futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset,unsign
        int x=0,y=0;
        int g_errno;
        unsigned long bp = stack_frame(current,NULL);
+       _spin_value *value =NULL;
+       _local_rq_t *l =NULL;
+       struct spin_key sk;
+       __spin_key_init(&sk);
+
 
 
        FPRINTK(KERN_ALERT " FUTEX_WAKE:current{%d} uaddr {%lx} get_user{%d} comm{%s}  lockval{%d} fn_flags{%d} cpu{%d} \n",current->pid,uaddr,x,current->comm,y,fn_flags,smp_processor_id());
@@ -1157,7 +1158,7 @@ futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset,unsign
                return -EINVAL;
 
        ret = (_tsk == NULL) ? get_futex_key(uaddr, flags & FLAGS_SHARED, &key, VERIFY_READ) :
-                get_futex_key_tsk(uaddr, flags & FLAGS_SHARED, &key, VERIFY_READ, _tsk);
+               get_futex_key_tsk(uaddr, flags & FLAGS_SHARED, &key, VERIFY_READ, _tsk);
 
        if (unlikely(ret != 0))
                goto out;
@@ -1166,58 +1167,69 @@ cont:
        hb = hash_futex(&key);
        if( !_tsk && !(flags & FLAGS_SHARED) && current->tgroup_distributed  && !(fn_flags & FLAGS_REMOTECALL) ){
                g_errno= global_queue_wake_lock(&key,uaddr, flags & FLAGS_SHARED, nr_wake, bitset,
-                                0, fn_flags, 0,0,0);
-               FPRINTK(KERN_ALERT " %s: err {%d}\n",__func__,g_errno);
+                               0, fn_flags, 0,0,0);
+               FPRINTK(KERN_ALERT " %s: err {%d}\n",__func__,g_errno);
                ret = g_errno;
                goto out;
        }
        else{
-       spin_lock(&hb->lock);
-       head = &hb->chain;
+               spin_lock(&hb->lock);
+               head = &hb->chain;
 
 
-       if((fn_flags & FLAGS_REMOTECALL))
-               fn_flags  &= ~(1 << 5); //FLAGS_ORIGINCALL
+               if((fn_flags & FLAGS_REMOTECALL))
+                       fn_flags  &= ~(1 << 5); //FLAGS_ORIGINCALL
 
-       plist_for_each_entry_safe(this, next, head, list) {
+               plist_for_each_entry_safe(this, next, head, list) {
 
-               if (match_futex (&this->key, &key)) {
-                       if (this->rem_pid == -1 && (this->pi_state || this->rt_waiter)) {
-                               ret = -EINVAL;
-                               break;
+                       if(_tsk){
+                               getKey(uaddr, &sk,_tsk->tgroup_home_id);
+                               value = hashspinkey(&sk);
                        }
-                       FPRINTK(KERN_ALERT "%s: inside match futex rem pid{%d} pid{%d}\n",__func__,this->rem_pid,(this->rem_pid==-1)?this->task->pid:0);
 
-                       /* Check if one of the bits is set in both bitsets */
-                       if (this->rem_pid == -1 && !(this->bitset & bitset))
-                               continue;
-                       if(this->rem_pid == -1)
-                        wake_futex(this);
-                       else
-                       {
-                               FPRINTK(KERN_ALERT " %s:sending it to remote after decision; ret{%d} nr_wake{%d} has_req_addr{%lx} \n",__func__,ret,nr_wake,(this->req_addr != 0) ? this->req_addr : 0);
-                               ret = remote_futex_wakeup(uaddr, flags & FLAGS_SHARED,nr_wake, bitset,&key,this->rem_pid, fn_flags, (this->req_addr != 0) ? this->req_addr : 0,0,0);
-                               this->rem_pid = NULL;
-                               this->req_addr = 0;
-                               __unqueue_futex(this);
-                               smp_wmb();
-                               this->lock_ptr = NULL;
+                       if (match_futex (&this->key, &key)) {
+                               if (this->rem_pid == -1 && (this->pi_state || this->rt_waiter)) {
+                                       ret = -EINVAL;
+                                       break;
+                               }
+                               FPRINTK(KERN_ALERT "%s: inside match futex rem pid{%d} pid{%d}\n",__func__,this->rem_pid,(this->rem_pid==-1)?this->task->pid:0);
+
+                               /* Check if one of the bits is set in both bitsets */
+                               if (this->rem_pid == -1 && !(this->bitset & bitset))
+                                       continue;
+                               if(this->rem_pid == -1){
+                                       if(_tsk){  
+                                               l= find_request_by_ops(0, uaddr, this->task->pid, &value->_lrq_head);
+                                               if(l) l->wake_st = 1;
+                                       }
+                                       wake_futex(this);
+                               }
+                               else
+                               {
+                                       FPRINTK(KERN_ALERT " %s:sending it to remote after decision; ret{%d} nr_wake{%d} has_req_addr{%lx} \n",__func__,ret,nr_wake,(this->req_addr != 0) ? this->req_addr : 0);
+                                       ret = remote_futex_wakeup(uaddr, flags & FLAGS_SHARED,nr_wake, bitset,&key,this->rem_pid, fn_flags, (this->req_addr != 0) ? this->req_addr : 0,0,0);
+                                       this->rem_pid = NULL;
+                                       this->req_addr = 0;
+                                       __unqueue_futex(this);
+                                       smp_wmb();
+                                       this->lock_ptr = NULL;
+                               }
+
+                               if (++ret >= nr_wake)
+                                       break;
                        }
                }
-               if (++ret >= nr_wake)
-                       break;
-       }
 
 
-       spin_unlock(&hb->lock);
-       put_futex_key(&key);
+               spin_unlock(&hb->lock);
+               put_futex_key(&key);
        }
-       
+
 out:
 #ifdef FUTEX_STAT
        if(!_tsk && current->tgroup_distributed){
                wake_bb = native_read_tsc();
-               _wake += wake_bb - wake_aa;
+               _wake += wake_bb - wake_aa;
        }
 #endif
        FPRINTK(KERN_ALERT "%s: exit {%d}\n",__func__,current->pid);
@@ -1227,88 +1239,88 @@ out:
 
 struct vm_area_struct * getVMAfromUaddr_t(unsigned long uaddr,struct task_struct *t) {
 
-  unsigned long address = (unsigned long) uaddr;
-  unsigned long offset = address % PAGE_SIZE;
-  if (unlikely((address % sizeof(u32)) != 0))
+       unsigned long address = (unsigned long) uaddr;
+       unsigned long offset = address % PAGE_SIZE;
+       if (unlikely((address % sizeof(u32)) != 0))
                return NULL;
-  address -= offset;
-  struct vm_area_struct *vma;
-  struct vm_area_struct* curr = NULL;
-  curr = t->mm->mmap;
-  vma = find_extend_vma(t->mm, address);
-  if (!vma)
-       return NULL;
-  else
-        return vma;
+       address -= offset;
+       struct vm_area_struct *vma;
+       struct vm_area_struct* curr = NULL;
+       curr = t->mm->mmap;
+       vma = find_extend_vma(t->mm, address);
+       if (!vma)
+               return NULL;
+       else
+               return vma;
 }
 
 static void dumpPTE(pte_t *ptep) {
 
- int nx;
- int rw;
- int user;
- int pwt;
- int pcd;
- int accessed;
- int dirty;
-unsigned long pfn;
      int nx;
      int rw;
      int user;
      int pwt;
      int pcd;
      int accessed;
      int dirty;
+       unsigned long pfn;
 
-pte_t pte;
-pte = *ptep;
+       pte_t pte;
+       pte = *ptep;
 
-printk(KERN_ALERT"cpu {%d} pte ptr: 0x{%lx}\n", smp_processor_id(), pte);
-pfn = pte_pfn(pte);
-printk(KERN_ALERT" cpu{%d} pte pfn : 0x{%lx}\n", smp_processor_id(), pfn);
+       printk(KERN_ALERT"cpu {%d} pte ptr: 0x{%lx}\n", smp_processor_id(), pte);
+       pfn = pte_pfn(pte);
+       printk(KERN_ALERT" cpu{%d} pte pfn : 0x{%lx}\n", smp_processor_id(), pfn);
 
-  nx       = pte_flags(*ptep) & _PAGE_NX       ? 1 : 0;
-  rw       = pte_flags(*ptep) & _PAGE_RW       ? 1 : 0;
-  user     = pte_flags(*ptep) & _PAGE_USER     ? 1 : 0;
-  pwt      = pte_flags(*ptep) & _PAGE_PWT      ? 1 : 0;
-  pcd      = pte_flags(*ptep) & _PAGE_PCD      ? 1 : 0;
-  accessed = pte_flags(*ptep) & _PAGE_ACCESSED ? 1 : 0;
-  dirty    = pte_flags(*ptep) & _PAGE_DIRTY    ? 1 : 0;
+       nx       = pte_flags(*ptep) & _PAGE_NX       ? 1 : 0;
+       rw       = pte_flags(*ptep) & _PAGE_RW       ? 1 : 0;
+       user     = pte_flags(*ptep) & _PAGE_USER     ? 1 : 0;
+       pwt      = pte_flags(*ptep) & _PAGE_PWT      ? 1 : 0;
+       pcd      = pte_flags(*ptep) & _PAGE_PCD      ? 1 : 0;
+       accessed = pte_flags(*ptep) & _PAGE_ACCESSED ? 1 : 0;
+       dirty    = pte_flags(*ptep) & _PAGE_DIRTY    ? 1 : 0;
 
-printk("\tnx{%d}, rw{%d} user{%d} pwt{%d} pcd{%d} accessed{%d} dirty{%d} present{%d} global{%d} special{%d} ",nx,rw,user,pwt,pcd,accessed,dirty,pte_present(pte),pte_mkglobal(pte),pte_mkspecial(pte));
+       printk("\tnx{%d}, rw{%d} user{%d} pwt{%d} pcd{%d} accessed{%d} dirty{%d} present{%d} global{%d} special{%d} ",nx,rw,user,pwt,pcd,accessed,dirty,pte_present(pte),pte_mkglobal(pte),pte_mkspecial(pte));
 
 
 exit:
-printk("exit\n");
+       printk("exit\n");
 }
 
 
- void dump_pgtable(unsigned long address)
+void dump_pgtable(unsigned long address)
 {
-pgd_t *base = __va(read_cr3() & PHYSICAL_PAGE_MASK);
-pgd_t *pgd = base + pgd_index(address);
-pud_t *pud;
-pmd_t *pmd;
-pte_t *pte;
-if (!pgd || !pgd_present(*pgd))
-       goto bad;
-printk(KERN_ALERT"PGD %lx flags{%d} ", pgd_val(*pgd),pgd_flags(*pgd));
-if (!pgd_present(*pgd))
+       pgd_t *base = __va(read_cr3() & PHYSICAL_PAGE_MASK);
+       pgd_t *pgd = base + pgd_index(address);
+       pud_t *pud;
+       pmd_t *pmd;
+       pte_t *pte;
+       if (!pgd || !pgd_present(*pgd))
+               goto bad;
+       printk(KERN_ALERT"PGD %lx flags{%d} ", pgd_val(*pgd),pgd_flags(*pgd));
+       if (!pgd_present(*pgd))
                goto out;
-pud = pud_offset(pgd, address);
-if (!pud || !pud_present(*pud))
+       pud = pud_offset(pgd, address);
+       if (!pud || !pud_present(*pud))
                goto bad;
-printk(KERN_ALERT"PUD %lx flags{%lx} ", pud_val(*pud),pud_flags(*pud));
-if (!pud || !pud_present(*pud) || pud_large(*pud))
+       printk(KERN_ALERT"PUD %lx flags{%lx} ", pud_val(*pud),pud_flags(*pud));
+       if (!pud || !pud_present(*pud) || pud_large(*pud))
                goto out;
-pmd = pmd_offset(pud, address);
-if (!pmd || !pmd_present(*pmd))
+       pmd = pmd_offset(pud, address);
+       if (!pmd || !pmd_present(*pmd))
                goto bad;
-printk(KERN_ALERT"PMD %lx mkold{%d} dirty{%d} mkwrite{%d} ", pmd_val(*pmd),pmd_mkold(*pmd),pmd_mkdirty(*pmd),pmd_mkwrite(*pmd));
-if (!pmd_present(*pmd) || pmd_large(*pmd))
+       printk(KERN_ALERT"PMD %lx mkold{%d} dirty{%d} mkwrite{%d} ", pmd_val(*pmd),pmd_mkold(*pmd),pmd_mkdirty(*pmd),pmd_mkwrite(*pmd));
+       if (!pmd_present(*pmd) || pmd_large(*pmd))
                goto out;
-pte = pte_offset_kernel(pmd, address);
-if (!(pte) || !pte_present(*pte))
+       pte = pte_offset_kernel(pmd, address);
+       if (!(pte) || !pte_present(*pte))
                goto bad;
-printk(KERN_ALERT"PTE %lx", pte_val(*pte));
+       printk(KERN_ALERT"PTE %lx", pte_val(*pte));
 out:
-printk(KERN_ALERT"\n");
-return;
+       printk(KERN_ALERT"\n");
+       return;
 bad:
-printk(KERN_ALERT"BAD\n");
+       printk(KERN_ALERT"BAD\n");
 }
 
 pte_t *do_page_wlk(unsigned long address,struct task_struct *t) {
@@ -1318,60 +1330,52 @@ pte_t *do_page_wlk(unsigned long address,struct task_struct *t) {
        pte_t *ptep = NULL;
        pte_t *pte;
        struct mm_struct *_m = t->mm;
-       //printk(KERN_ALERT"mm{%p} cm{%p} am{%p} \n",_m,(!current->mm) ? 0 : current->mm, (!current->active_mm) ? 0 :current->active_mm);
-       //down_read(&_m->mmap_sem);
 
        pgd = pgd_offset(_m, address);
        if (!pgd_present(*pgd)) {
-       //      up_read(&_m->mmap_sem);
                goto exit;
        }
-      printk(KERN_ALERT"PGD %lx flags{%d} ", pgd_val(*pgd),pgd_flags(*pgd));
-  
+       printk(KERN_ALERT"PGD %lx flags{%d} ", pgd_val(*pgd),pgd_flags(*pgd));
+
        pud = pud_offset(pgd, address);
        if (!pud_present(*pud)) {
-       //      up_read(&_m->mmap_sem);
                goto exit;
        }
-printk(KERN_ALERT"PUD %lx flags{%lx} ", pud_val(*pud),pud_flags(*pud));
+       printk(KERN_ALERT"PUD %lx flags{%lx} ", pud_val(*pud),pud_flags(*pud));
 
        pmd = pmd_offset(pud, address);
        if (!pmd_present(*pmd)) {
-       //      up_read(&_m->mmap_sem);
                goto exit;
        }
-printk(KERN_ALERT"PMD %lx mkold{%d} dirty{%d} mkwrite{%d}  pmd_flags{%lx}", pmd_val(*pmd),pmd_mkold(*pmd),pmd_mkdirty(*pmd),pmd_mkwrite(*pmd),pmd_flags(*pmd));
+       printk(KERN_ALERT"PMD %lx mkold{%d} dirty{%d} mkwrite{%d}  pmd_flags{%lx}", pmd_val(*pmd),pmd_mkold(*pmd),pmd_mkdirty(*pmd),pmd_mkwrite(*pmd),pmd_flags(*pmd));
        ptep = pte_offset_map(pmd, address);
        if (!ptep || !pte_present(*ptep)) {
-       //      up_read(&_m->mmap_sem);
                goto exit;
        }
        pte = ptep;
 
-       //up_read(&_m->mmap_sem);
        return (pte_t*) pte;
 exit: 
-//     up_read(&_m->mmap_sem);
        return NULL;
 }
 
 
 void find_page(unsigned long uaddr,struct task_struct *t){
 
-pte_t *pt=do_page_wlk(uaddr,t);
-printk(KERN_ALERT"%s: dump PTE with normal page walk using mm\n",__func__);
-dumpPTE(pt);
-printk(KERN_ALERT"%s: dump PTE with CR3 \n",__func__);
-dump_pgtable(uaddr);
+       pte_t *pt=do_page_wlk(uaddr,t);
+       printk(KERN_ALERT"%s: dump PTE with normal page walk using mm\n",__func__);
+       dumpPTE(pt);
+       printk(KERN_ALERT"%s: dump PTE with CR3 \n",__func__);
+       dump_pgtable(uaddr);
 
-struct vm_area_struct * _v = getVMAfromUaddr_t(uaddr,t);
-struct page * pg = vm_normal_page(_v, uaddr,*pt);
-if(!pg)
- printk(KERN_ALERT"%s: pg not so good news\n",__func__);
-else{
-       dump_page(pg);
- printk(KERN_ALERT"%s: pg present vm{%lx} end{%lx}  flags{%lx} pageprot{%lx} \n",__func__,_v->vm_start, _v->vm_end,_v->vm_flags, pgprot_val(_v->vm_page_prot));
-}
+       struct vm_area_struct * _v = getVMAfromUaddr_t(uaddr,t);
+       struct page * pg = vm_normal_page(_v, uaddr,*pt);
+       if(!pg)
              printk(KERN_ALERT"%s: pg not so good news\n",__func__);
+       else{
+               dump_page(pg);
              printk(KERN_ALERT"%s: pg present vm{%lx} end{%lx}  flags{%lx} pageprot{%lx} \n",__func__,_v->vm_start, _v->vm_end,_v->vm_flags, pgprot_val(_v->vm_page_prot));
+       }
 }
 /*
  * Wake up all waiters hashed on the physical page that is mapped
@@ -1379,7 +1383,7 @@ else{
  */
 //static
 int futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2,
-             int nr_wake, int nr_wake2, int op,unsigned int fn_flags,struct task_struct * or_task)
+               int nr_wake, int nr_wake2, int op,unsigned int fn_flags,struct task_struct * or_task)
 {
 
 #ifdef FUTEX_STAT
@@ -1399,13 +1403,17 @@ int futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2,
        int g_errno=0;
        int x=0;
        struct mm_struct *act=NULL,*old=NULL;
+       _spin_value *value1 =NULL, *value2 =NULL;
+       _local_rq_t *l =NULL;
+       struct spin_key sk;
+       __spin_key_init(&sk);
 
        fn_flags |= FLAGS_WAKEOPCALL;
        FPRINTK(KERN_ALERT " FUTEX_WAKE_OP: entry{%pB} pid {%d} comm{%s} uaddr1{%lx} uaddr2{%lx}  op(%d} \n",(void*) &bp,current->pid,current->comm,uaddr1,uaddr2,op);
 retry:
        ret = (or_task == NULL) ? get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1, VERIFY_READ) :
                get_futex_key_tsk(uaddr1, flags & FLAGS_SHARED, &key1, VERIFY_READ, or_task);
-       
+
 
        if (unlikely(ret != 0))
                goto out;
@@ -1421,136 +1429,140 @@ retry:
        hb2 = hash_futex(&key2);
 
 retry_private:
-       
-       /*if((strcmp("cond",current->comm) == 0 ) || (strcmp("mut",current->comm) == 0) || (strcmp("bar",current->comm))){
-       printk(KERN_ALERT"%s: distriuted {%d} cpu{%d} pid{%d} uaddr{%lx} or{%d} ordiswsd{%d}\n",__func__,current->tgroup_distributed,smp_processor_id(),current->pid,uaddr1,(or_task) ? or_task->pid : 0, (or_task) ? or_task->tgroup_distributed : 0);
-       }*/
+
        if(or_task){
                use_mm(or_task->mm);
        }
 
        if( !or_task && current->tgroup_distributed  && !(fn_flags & FLAGS_REMOTECALL) && !(flags & FLAGS_SHARED)){
-               //struct vm_area_struct  *_v = getVMAfromUaddr(uaddr2);
-               //printk(KERN_ALERT "%s:comm{%s} start{%lx} end{%lx} vmastart{%lx} vmaend{%lx} vmaflag{%lx}\n",__func__,current->comm,current->mm->mmap->vm_start, current->mm->mmap->vm_end, _v->vm_start,_v->vm_end,_v->vm_flags);
-               //find_page(uaddr2,current);
+               //find_page(uaddr2,current);
                g_errno= global_queue_wake_lock(&key1,uaddr1, flags & FLAGS_SHARED, nr_wake, 1,
-                                0, fn_flags,uaddr2,nr_wake2,op);
-               ret = g_errno;
-               FPRINTK(KERN_ALERT " %s: err {%d}\n",__func__,g_errno);
+                               0, fn_flags,uaddr2,nr_wake2,op);
+               ret = g_errno;
+               FPRINTK(KERN_ALERT " %s: err {%d}\n",__func__,g_errno);
 #ifdef FUTEX_STAT
                _wakeop_err++;
 #endif
-               goto out;
+               goto out;
        }
        else
        {
-               
-       //printk(KERN_ALERT"%s:  \n",__func__);
-       double_lock_hb(hb1, hb2);
-       op_ret = futex_atomic_op_inuser(op, (u32 __user *)uaddr2);
-       if (unlikely(op_ret < 0)) {
 
-               double_unlock_hb(hb1, hb2);
+               double_lock_hb(hb1, hb2);
+               op_ret = futex_atomic_op_inuser(op, (u32 __user *)uaddr2);
+               if (unlikely(op_ret < 0)) {
+
+                       double_unlock_hb(hb1, hb2);
 #ifndef CONFIG_MMU
-               /*
-                * we don't get EFAULT from MMU faults if we don't have an MMU,
-                * but we might get them from range checking
-                */
-               ret = op_ret;
-               goto out_put_keys;
-#endif
-               if (unlikely(op_ret != -EFAULT)) {
+                       /*
+                        * we don't get EFAULT from MMU faults if we don't have an MMU,
+                        * but we might get them from range checking
+                        */
                        ret = op_ret;
                        goto out_put_keys;
-               }
-               if((fn_flags & FLAGS_REMOTECALL) && or_task && op_ret == -EFAULT){
-                 flush_cache_mm(or_task->mm);
-               }
-
-               ret = ((fn_flags & FLAGS_REMOTECALL) && or_task)? fault_in_user_writeable_task(uaddr2,or_task):fault_in_user_writeable(uaddr2);
-               
-               if(or_task){
-               //struct vm_area_struct *_v = getVMAfromUaddr_t(uaddr2,or_task);
-               //printk(KERN_ALERT "%s: faultinuaddr2 op{%d} ret{%d} valu{%d} tsk{%d} comm{%s} start{%lx} end{%lx} vmstart{%lx} vmend{%lx} vmflag{%lx}\n",__func__,op,ret,x,or_task->pid,or_task->comm,or_task->mm->mmap->vm_start, or_task->mm->mmap->vm_end, (_v) ? _v->vm_start : 0,(_v) ? _v->vm_end : 0, (_v) ?_v->vm_flags : 0);
-               //find_page(uaddr2,or_task);
-               }
-
-               if((fn_flags & FLAGS_REMOTECALL) && or_task && op_ret == -EFAULT){
-                 flush_tlb_page(or_task->mm->mmap, uaddr2);
-                 unuse_mm(or_task->mm);
-               }
-               if (ret)
-                       goto out_put_keys;
+#endif
+                       if (unlikely(op_ret != -EFAULT)) {
+                               ret = op_ret;
+                               goto out_put_keys;
+                       }
 
-               if (!(flags & FLAGS_SHARED))
-                       goto retry_private;
+                       ret = ((fn_flags & FLAGS_REMOTECALL) && or_task)? fault_in_user_writeable_task(uaddr2,or_task):fault_in_user_writeable(uaddr2);
 
-               put_futex_key(&key2);
-               put_futex_key(&key1);
-               goto retry;
-       }
 
-       if((fn_flags & FLAGS_REMOTECALL) && or_task){
-       unuse_mm(or_task->mm);
-       }
-       if((fn_flags & FLAGS_REMOTECALL)){
-       fn_flags  = 0;
-       fn_flags |=FLAGS_WAKEOPCALL;//FLAGS_ORIGINCALL
-       }
+                       if((fn_flags & FLAGS_REMOTECALL) && or_task && op_ret == -EFAULT){
+                               unuse_mm(or_task->mm);
+                       }
+                       if (ret)
+                               goto out_put_keys;
 
+                       if (!(flags & FLAGS_SHARED))
+                               goto retry_private;
 
+                       put_futex_key(&key2);
+                       put_futex_key(&key1);
+                       goto retry;
+               }
 
-       head = &hb1->chain;
+               if((fn_flags & FLAGS_REMOTECALL) && or_task){
+                       unuse_mm(or_task->mm);
+               }
+               if((fn_flags & FLAGS_REMOTECALL)){
+                       fn_flags  = 0;
+                       fn_flags |=FLAGS_WAKEOPCALL;
+               }
 
-       plist_for_each_entry_safe(this, next, head, list)
-       {
 
-               FPRINTK(KERN_ALERT "%s:key1 pid{%d} comm{%s} rem{%d}\n",__func__,current->pid,current->comm,this->rem_pid);
-               if (match_futex (&this->key, &key1)) {
-                       if(this->rem_pid == -1)
-                               wake_futex(this);
-                       else
-                       {       u32 bitset=1;
-                       ret = remote_futex_wakeup(uaddr1, flags & FLAGS_SHARED,nr_wake, bitset,&key1,this->rem_pid, fn_flags, 0,0,0);
-                       this->rem_pid=NULL;
-                       __unqueue_futex(this);
-                       smp_wmb();
-                       this->lock_ptr = NULL;
-                       }
 
-                       if (++ret >= nr_wake)
-                               break;
+               head = &hb1->chain;
+               if(or_task){
+                       getKey(uaddr1, &sk,or_task->tgroup_home_id);
+                       value1 = hashspinkey(&sk);
                }
-       }
 
-       if (op_ret > 0) {
-               head = &hb2->chain;
 
-               op_ret = 0;
                plist_for_each_entry_safe(this, next, head, list)
                {
 
-                       FPRINTK(KERN_ALERT "%s:key2 pid{%d} comm{%s} rem{%d}\n",__func__,current->pid,current->comm,this->rem_pid);
-                       if (match_futex (&this->key, &key2)) {
-                               if(this->rem_pid == -1)
+                       FPRINTK(KERN_ALERT "%s:key1 pid{%d} comm{%s} rem{%d}\n",__func__,current->pid,current->comm,this->rem_pid);
+                       if (match_futex (&this->key, &key1)) {
+                               if(this->rem_pid == -1){
+                                       if(or_task){
+                                               l= find_request_by_ops(0, uaddr1, this->task->pid, &value1->_lrq_head);
+                                               if(l) l->wake_st = 1;
+                                       }
                                        wake_futex(this);
+                               }
                                else
                                {       u32 bitset=1;
-                               ret = remote_futex_wakeup(uaddr2, flags & FLAGS_SHARED,nr_wake, bitset,&key2,this->rem_pid, fn_flags, 0,0,0);
-                               this->rem_pid=NULL;
-                               __unqueue_futex(this);
-                               smp_wmb();
-                               this->lock_ptr = NULL;
+                                       ret = remote_futex_wakeup(uaddr1, flags & FLAGS_SHARED,nr_wake, bitset,&key1,this->rem_pid, fn_flags, 0,0,0);
+                                       this->rem_pid=NULL;
+                                       __unqueue_futex(this);
+                                       smp_wmb();
+                                       this->lock_ptr = NULL;
                                }
 
-                               if (++op_ret >= nr_wake2)
+                               if (++ret >= nr_wake)
                                        break;
                        }
                }
-               ret += op_ret;
-       }
+               if(or_task){
+                       getKey(uaddr2, &sk,or_task->tgroup_home_id);
+                       value2 = hashspinkey(&sk);
+               }
 
-       double_unlock_hb(hb1, hb2);
+               if (op_ret > 0) {
+                       head = &hb2->chain;
+
+                       op_ret = 0;
+                       plist_for_each_entry_safe(this, next, head, list)
+                       {
+
+                               FPRINTK(KERN_ALERT "%s:key2 pid{%d} comm{%s} rem{%d}\n",__func__,current->pid,current->comm,this->rem_pid);
+                               if (match_futex (&this->key, &key2)) {
+                                       if(this->rem_pid == -1){
+                                               if(or_task){                                                                                    l= find_request_by_ops(0, uaddr2, this->task->pid, &value2->_lrq_head);
+                                                       if(l)   l->wake_st = 1;
+                                               }
+
+                                               wake_futex(this);
+                                       }
+                                       else
+                                       {       u32 bitset=1;
+                                               ret = remote_futex_wakeup(uaddr2, flags & FLAGS_SHARED,nr_wake, bitset,&key2,this->rem_pid, fn_flags, 0,0,0);
+                                               this->rem_pid=NULL;
+                                               __unqueue_futex(this);
+                                               smp_wmb();
+                                               this->lock_ptr = NULL;
+                                       }
+
+                                       if (++op_ret >= nr_wake2)
+                                               break;
+                               }
+                       }
+                       ret += op_ret;
+               }
+
+               double_unlock_hb(hb1, hb2);
 
        }
 out_put_keys:
@@ -1562,7 +1574,7 @@ out:
 #ifdef FUTEX_STAT
        if(!or_task && current->tgroup_distributed){
                wakeop_bb = native_read_tsc();
-               _wakeop += wakeop_bb - wakeop_aa;
+               _wakeop += wakeop_bb - wakeop_aa;
        }
 #endif
        return ret;
@@ -1575,9 +1587,9 @@ out:
  * @hb2:       the target hash_bucket
  * @key2:      the new key for the requeued futex_q
  */
-static inline
+       static inline
 void requeue_futex(struct futex_q *q, struct futex_hash_bucket *hb1,
-                  struct futex_hash_bucket *hb2, union futex_key *key2)
+               struct futex_hash_bucket *hb2, union futex_key *key2)
 {
 
        /*
@@ -1593,10 +1605,9 @@ void requeue_futex(struct futex_q *q, struct futex_hash_bucket *hb1,
        q->key = *key2;
 }
 
-static inline
+       static inline
 void rem_requeue_futex(struct futex_q *q, union futex_key *key2, unsigned long uaddr)
 {
-
        q->req_addr = uaddr;
        q->rem_requeue_key = *key2;
 }
@@ -1617,9 +1628,9 @@ void rem_requeue_futex(struct futex_q *q, union futex_key *key2, unsigned long u
  * to protect access to the pi_state to fixup the owner later.  Must be called
  * with both q->lock_ptr and hb->lock held.
  */
-static inline
+       static inline
 void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key,
-                          struct futex_hash_bucket *hb)
+               struct futex_hash_bucket *hb)
 {
        get_futex_key_refs(key);
        q->key = *key;
@@ -1655,10 +1666,10 @@ void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key,
  * <0 - error
  */
 static int futex_proxy_trylock_atomic(u32 __user *pifutex,
-                                struct futex_hash_bucket *hb1,
-                                struct futex_hash_bucket *hb2,
-                                union futex_key *key1, union futex_key *key2,
-                                struct futex_pi_state **ps, int set_waiters)
+               struct futex_hash_bucket *hb1,
+               struct futex_hash_bucket *hb2,
+               union futex_key *key1, union futex_key *key2,
+               struct futex_pi_state **ps, int set_waiters)
 {
        struct futex_q *top_waiter = NULL;
        u32 curval;
@@ -1691,7 +1702,7 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex,
         * in ps in contended cases.
         */
        ret = futex_lock_pi_atomic(pifutex, hb2, key2, ps, top_waiter->task,
-                                  set_waiters);
+                       set_waiters);
        if (ret == 1)
                requeue_pi_wake_futex(top_waiter, key2, hb2);
 
@@ -1718,8 +1729,8 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex,
  */
 //static
 int futex_requeue(u32 __user *uaddr1, unsigned int flags,
-                        u32 __user *uaddr2, int nr_wake, int nr_requeue,
-                        u32 *cmpval, int requeue_pi,unsigned int fn_flags, struct task_struct * re_task)
+               u32 __user *uaddr2, int nr_wake, int nr_requeue,
+               u32 *cmpval, int requeue_pi,unsigned int fn_flags, struct task_struct * re_task)
 {
 
 #ifdef FUTEX_STAT
@@ -1740,6 +1751,10 @@ int futex_requeue(u32 __user *uaddr1, unsigned int flags,
        int requeued=0;
        int g_errno=0;
        unsigned long bp = stack_frame(current,NULL);
+       _spin_value *value1 =NULL, *value2 =NULL;
+       _local_rq_t *l =NULL;
+       struct spin_key sk;
+       __spin_key_init(&sk);
 
        fn_flags |= FLAGS_REQCALL;
 
@@ -1783,7 +1798,7 @@ retry:
 
        ret = (re_task == NULL) ? get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, requeue_pi ? VERIFY_WRITE : VERIFY_READ) :
                get_futex_key_tsk(uaddr2, flags & FLAGS_SHARED, &key2,  requeue_pi ? VERIFY_WRITE : VERIFY_READ, re_task);
-       
+
        if (unlikely(ret != 0))
                goto out_put_key1;
 
@@ -1794,194 +1809,204 @@ cont:
 
 retry_private:
 
-    FPRINTK(KERN_ALERT " %s: spinlock  futex_requeue uaddr2{%lx} \n",__func__,uaddr2);
+       FPRINTK(KERN_ALERT " %s: spinlock  futex_requeue uaddr2{%lx} \n",__func__,uaddr2);
 
-    if(re_task){
-           use_mm(re_task->mm);
-    }
+       if(re_task){
+               use_mm(re_task->mm);
+       }
 
-    if( !re_task && current->tgroup_distributed  && !(fn_flags & FLAGS_REMOTECALL) && !(flags & FLAGS_SHARED)){
-               g_errno= global_queue_wake_lock(&key1,uaddr1, flags & FLAGS_SHARED, nr_wake, 1,
-                                0, fn_flags,uaddr2,nr_requeue,(int)*cmpval);
-               FPRINTK(KERN_ALERT " %s: err {%d}\n",__func__,g_errno);
-               ret = g_errno;
+       if( !re_task && current->tgroup_distributed  && !(fn_flags & FLAGS_REMOTECALL) && !(flags & FLAGS_SHARED)){
+               g_errno= global_queue_wake_lock(&key1,uaddr1, flags & FLAGS_SHARED, nr_wake, 1,
+                               0, fn_flags,uaddr2,nr_requeue,(int)*cmpval);
+               FPRINTK(KERN_ALERT " %s: err {%d}\n",__func__,g_errno);
+               ret = g_errno;
 #ifdef FUTEX_STAT
                _requeue_err++;
 #endif
-               goto out;
-    }
-    else
-    {
-       double_lock_hb(hb1, hb2);
+               goto out;
+       }
+       else
+       {
+               double_lock_hb(hb1, hb2);
 
-       if (likely(cmpval != NULL)) {
-               u32 curval;
+               if (likely(cmpval != NULL)) {
+                       u32 curval;
 
-               ret = get_futex_value_locked(&curval, uaddr1);
+                       ret = get_futex_value_locked(&curval, uaddr1);
 
-               if (unlikely(ret)) {
-                       double_unlock_hb(hb1, hb2);
+                       if (unlikely(ret)) {
+                               double_unlock_hb(hb1, hb2);
 
-                       //if(re_task && ret == -EFAULT)
-                       //      get_user_pages_fast_mm(re_task->mm, key1.private.address, 1, 1, pages);
+                               //if(re_task && ret == -EFAULT)
+                               //      get_user_pages_fast_mm(re_task->mm, key1.private.address, 1, 1, pages);
 
-                       ret = get_user(curval, uaddr1);
-                       if (ret)
-                               goto out_put_keys;
-                        
-                       if(re_task && ret == -EFAULT)
-                               unuse_mm(re_task->mm);
+                               ret = get_user(curval, uaddr1);
+                               if (ret)
+                                       goto out_put_keys;
 
+                               if(re_task && ret == -EFAULT)
+                                       unuse_mm(re_task->mm);
 
-                       if (!(flags & FLAGS_SHARED))
-                               goto retry_private;
-          
-                       put_futex_key(&key2);
-                       put_futex_key(&key1);
-                       goto retry;
-               }
-               if (curval != *cmpval) {
-                       ret = -EAGAIN;
-                       goto out_unlock;
-               }
-       }
 
-       if (requeue_pi && (task_count - nr_wake < nr_requeue)) {
-               /*
-                * Attempt to acquire uaddr2 and wake the top waiter. If we
-                * intend to requeue waiters, force setting the FUTEX_WAITERS
-                * bit.  We force this here where we are able to easily handle
-                * faults rather in the requeue loop below.
-                */
-               ret = futex_proxy_trylock_atomic(uaddr2, hb1, hb2, &key1,
-                                                &key2, &pi_state, nr_requeue);
-
-               /*
-                * At this point the top_waiter has either taken uaddr2 or is
-                * waiting on it.  If the former, then the pi_state will not
-                * exist yet, look it up one more time to ensure we have a
-                * reference to it.
-                */
-               if (ret == 1) {
-                       WARN_ON(pi_state);
-                       drop_count++;
-                       task_count++;
-                       ret = get_futex_value_locked(&curval2, uaddr2);
-                       if (!ret)
-                               ret = lookup_pi_state(curval2, hb2, &key2,
-                                                     &pi_state);
-               }
+                               if (!(flags & FLAGS_SHARED))
+                                       goto retry_private;
 
-               switch (ret) {
-               case 0:
-                       break;
-               case -EFAULT:
-                       double_unlock_hb(hb1, hb2);
-                       put_futex_key(&key2);
-                       put_futex_key(&key1);
-                       ret = fault_in_user_writeable(uaddr2);
-                       if (!ret)
+                               put_futex_key(&key2);
+                               put_futex_key(&key1);
                                goto retry;
-                       goto out;
-               case -EAGAIN:
-                       /* The owner was exiting, try again. */
-                       double_unlock_hb(hb1, hb2);
-                       put_futex_key(&key2);
-                       put_futex_key(&key1);
-                       cond_resched();
-                       goto retry;
-               default:
-                       goto out_unlock;
+                       }
+                       if (curval != *cmpval) {
+                               ret = -EAGAIN;
+                               goto out_unlock;
+                       }
                }
-       }
-
-       if((fn_flags & FLAGS_REMOTECALL) && re_task){
-               fn_flags  = 0;
-               fn_flags |=FLAGS_REQCALL;//FLAGS_ORIGINCALL
-               unuse_mm(re_task->mm);
-       }
 
-       head1 = &hb1->chain;
-       plist_for_each_entry_safe(this, next, head1, list) {
-               if (task_count - nr_wake >= nr_requeue)
-                       break;
+               if (requeue_pi && (task_count - nr_wake < nr_requeue)) {
+                       /*
+                        * Attempt to acquire uaddr2 and wake the top waiter. If we
+                        * intend to requeue waiters, force setting the FUTEX_WAITERS
+                        * bit.  We force this here where we are able to easily handle
+                        * faults rather in the requeue loop below.
+                        */
+                       ret = futex_proxy_trylock_atomic(uaddr2, hb1, hb2, &key1,
+                                       &key2, &pi_state, nr_requeue);
 
-               if (!match_futex(&this->key, &key1))
-                       continue;
+                       /*
+                        * At this point the top_waiter has either taken uaddr2 or is
+                        * waiting on it.  If the former, then the pi_state will not
+                        * exist yet, look it up one more time to ensure we have a
+                        * reference to it.
+                        */
+                       if (ret == 1) {
+                               WARN_ON(pi_state);
+                               drop_count++;
+                               task_count++;
+                               ret = get_futex_value_locked(&curval2, uaddr2);
+                               if (!ret)
+                                       ret = lookup_pi_state(curval2, hb2, &key2,
+                                                       &pi_state);
+                       }
 
-               /*
-                * FUTEX_WAIT_REQEUE_PI and FUTEX_CMP_REQUEUE_PI should always
-                * be paired with each other and no other futex ops.
-                */
-               if ((requeue_pi && !this->rt_waiter) ||
-                   (!requeue_pi && this->rt_waiter)) {
-                       ret = -EINVAL;
-                       break;
+                       switch (ret) {
+                               case 0:
+                                       break;
+                               case -EFAULT:
+                                       double_unlock_hb(hb1, hb2);
+                                       put_futex_key(&key2);
+                                       put_futex_key(&key1);
+                                       ret = fault_in_user_writeable(uaddr2);
+                                       if (!ret)
+                                               goto retry;
+                                       goto out;
+                               case -EAGAIN:
+                                       /* The owner was exiting, try again. */
+                                       double_unlock_hb(hb1, hb2);
+                                       put_futex_key(&key2);
+                                       put_futex_key(&key1);
+                                       cond_resched();
+                                       goto retry;
+                               default:
+                                       goto out_unlock;
+                       }
                }
 
-               /*
-                * Wake nr_wake waiters.  For requeue_pi, if we acquired the
-                * lock, we already woke the top_waiter.  If not, it will be
-                * woken by futex_unlock_pi().
-                */
-               FPRINTK(KERN_ALERT " %s: nr_wake{%d} task_count{%d} requeued{%d} pid{%d} fn_flags{%lx}\n",__func__,nr_wake,task_count,requeued,this->rem_pid,fn_flags);
-
-               if (++task_count <= nr_wake && !requeue_pi) {
-
-                       if(this->rem_pid == -1)
-                               wake_futex(this);
-                       else
-                       {       u32 bitset=1;
-                       if(!requeued)
-                               ret = remote_futex_wakeup(uaddr1, flags & FLAGS_SHARED,nr_wake, bitset,&key1,this->rem_pid, fn_flags,0,0,0);
-                       else
-                               ret = remote_futex_wakeup(uaddr2, flags & FLAGS_SHARED,nr_wake, bitset,&key2,this->rem_pid, fn_flags, 0,0,0);
-                       this->rem_pid=NULL;
-                       __unqueue_futex(this);
-                       smp_wmb();
-                       this->lock_ptr = NULL;
-                       }
-                       continue;
+               if((fn_flags & FLAGS_REMOTECALL) && re_task){
+                       fn_flags  = 0;
+                       fn_flags |=FLAGS_REQCALL;//FLAGS_ORIGINCALL
+                       unuse_mm(re_task->mm);
                }
 
-               /* Ensure we requeue to the expected futex for requeue_pi. */
-               if (requeue_pi && !match_futex(this->requeue_pi_key, &key2)) {
-                       ret = -EINVAL;
-                       break;
+               if(re_task){
+                       getKey(uaddr1, &sk,re_task->tgroup_home_id);
+                       value1 = hashspinkey(&sk);
                }
 
-               /*
-                * Requeue nr_requeue waiters and possibly one more in the case
-                * of requeue_pi if we couldn't acquire the lock atomically.
-                */
-               if (requeue_pi) {
-                       /* Prepare the waiter to take the rt_mutex. */
-                       atomic_inc(&pi_state->refcount);
-                       this->pi_state = pi_state;
-                       ret = rt_mutex_start_proxy_lock(&pi_state->pi_mutex,
-                                                       this->rt_waiter,
-                                                       this->task, 1);
-                       if (ret == 1) {
-                               /* We got the lock. */
-                               requeue_pi_wake_futex(this, &key2, hb2);
-                               drop_count++;
+               head1 = &hb1->chain;
+               plist_for_each_entry_safe(this, next, head1, list) {
+                       if (task_count - nr_wake >= nr_requeue)
+                               break;
+
+                       if (!match_futex(&this->key, &key1))
                                continue;
-                       } else if (ret) {
-                               /* -EDEADLK */
-                               this->pi_state = NULL;
-                               free_pi_state(pi_state);
-                               goto out_unlock;
+
+                       /*
+                        * FUTEX_WAIT_REQEUE_PI and FUTEX_CMP_REQUEUE_PI should always
+                        * be paired with each other and no other futex ops.
+                        */
+                       if ((requeue_pi && !this->rt_waiter) ||
+                                       (!requeue_pi && this->rt_waiter)) {
+                               ret = -EINVAL;
+                               break;
                        }
+
+                       /*
+                        * Wake nr_wake waiters.  For requeue_pi, if we acquired the
+                        * lock, we already woke the top_waiter.  If not, it will be
+                        * woken by futex_unlock_pi().
+                        */
+                       FPRINTK(KERN_ALERT " %s: nr_wake{%d} task_count{%d} requeued{%d} pid{%d} fn_flags{%lx}\n",__func__,nr_wake,task_count,requeued,this->rem_pid,fn_flags);
+
+                       if (++task_count <= nr_wake && !requeue_pi) {
+
+                               if(this->rem_pid == -1){
+                                       if(re_task){                                                                                            l= find_request_by_ops(0, uaddr1, this->task->pid, &value1->_lrq_head);
+                                               if(l)   l->wake_st = 1;
+                                       }
+
+                                       wake_futex(this);
+                               }
+                               else
+                               {       u32 bitset=1;
+                                       if(!requeued)
+                                               ret = remote_futex_wakeup(uaddr1, flags & FLAGS_SHARED,nr_wake, bitset,&key1,this->rem_pid, fn_flags,0,0,0);
+                                       else
+                                               ret = remote_futex_wakeup(uaddr2, flags & FLAGS_SHARED,nr_wake, bitset,&key2,this->rem_pid, fn_flags, 0,0,0);
+                                       this->rem_pid=NULL;
+                                       __unqueue_futex(this);
+                                       smp_wmb();
+                                       this->lock_ptr = NULL;
+                               }
+                               continue;
+                       }
+
+                       /* Ensure we requeue to the expected futex for requeue_pi. */
+                       if (requeue_pi && !match_futex(this->requeue_pi_key, &key2)) {
+                               ret = -EINVAL;
+                               break;
+                       }
+
+                       /*
+                        * Requeue nr_requeue waiters and possibly one more in the case
+                        * of requeue_pi if we couldn't acquire the lock atomically.
+                        */
+                       if (requeue_pi) {
+                               /* Prepare the waiter to take the rt_mutex. */
+                               atomic_inc(&pi_state->refcount);
+                               this->pi_state = pi_state;
+                               ret = rt_mutex_start_proxy_lock(&pi_state->pi_mutex,
+                                               this->rt_waiter,
+                                               this->task, 1);
+                               if (ret == 1) {
+                                       /* We got the lock. */
+                                       requeue_pi_wake_futex(this, &key2, hb2);
+                                       drop_count++;
+                                       continue;
+                               } else if (ret) {
+                                       /* -EDEADLK */
+                                       this->pi_state = NULL;
+                                       free_pi_state(pi_state);
+                                       goto out_unlock;
+                               }
+                       }
+                       FPRINTK(KERN_ALERT"%s: b4 requeue\n");
+                       requeue_futex(this, hb1, hb2, &key2);
+                       if(this->rem_pid != -1){
+                               rem_requeue_futex(this,&key1,(unsigned long) uaddr1);
+                       }
+                       requeued=1;
+                       drop_count++;
                }
-               FPRINTK(KERN_ALERT"%s: b4 requeue\n");
-               requeue_futex(this, hb1, hb2, &key2);
-               if(this->rem_pid != -1){
-                       rem_requeue_futex(this,&key1,(unsigned long) uaddr1);
-               }
-               requeued=1;
-               drop_count++;
        }
-    }
 
 out_unlock:
        double_unlock_hb(hb1, hb2);
@@ -2006,15 +2031,15 @@ out:
 #ifdef FUTEX_STAT
        if(!re_task && current->tgroup_distributed){
                requeue_bb = native_read_tsc();
-               _requeue += requeue_bb - requeue_aa;
+               _requeue += requeue_bb - requeue_aa;
        }
 #endif
        return ret ? ret : task_count;
 }
 
 /* The key must be already stored in q->key. */
-static inline struct futex_hash_bucket *queue_lock(struct futex_q *q)
-       __acquires(&hb->lock)
+       static inline struct futex_hash_bucket *queue_lock(struct futex_q *q)
+__acquires(&hb->lock)
 {
        struct futex_hash_bucket *hb;
 
@@ -2025,15 +2050,15 @@ static inline struct futex_hash_bucket *queue_lock(struct futex_q *q)
        return hb;
 }
 
-static inline void
-queue_unlock(struct futex_q *q, struct futex_hash_bucket *hb)
-       __releases(&hb->lock)
+       static inline void
+       queue_unlock(struct futex_q *q, struct futex_hash_bucket *hb)
+__releases(&hb->lock)
 {
        spin_unlock(&hb->lock);
 }
-static inline void
-global_queue_unlock(struct futex_q *q, struct futex_hash_bucket *hb)
-       __releases(&hb->lock)
+       static inline void
+       global_queue_unlock(struct futex_q *q, struct futex_hash_bucket *hb)
+__releases(&hb->lock)
 {
        //release the actual spinlock : Not necessary as we are alone
        spin_unlock(&hb->lock);
@@ -2053,8 +2078,8 @@ global_queue_unlock(struct futex_q *q, struct futex_hash_bucket *hb)
  * state is implicit in the state of woken task (see futex_wait_requeue_pi() for
  * an example).
  */
-static inline void queue_me(struct futex_q *q, struct futex_hash_bucket *hb)
-       __releases(&hb->lock)
+       static inline void queue_me(struct futex_q *q, struct futex_hash_bucket *hb)
+__releases(&hb->lock)
 {
        int prio;
 
@@ -2071,6 +2096,7 @@ static inline void queue_me(struct futex_q *q, struct futex_hash_bucket *hb)
        plist_node_init(&q->list, prio);
        plist_add(&q->list, &hb->chain);
        q->task = current;
+       smp_mb();
        spin_unlock(&hb->lock);
 
 
@@ -2132,8 +2158,8 @@ retry:
  * hash bucket. The hash bucket lock (i.e. lock_ptr) is held on entry
  * and dropped here.
  */
-static void unqueue_me_pi(struct futex_q *q)
-       __releases(q->lock_ptr)
+       static void unqueue_me_pi(struct futex_q *q)
+__releases(q->lock_ptr)
 {
        __unqueue_futex(q);
 
@@ -2151,7 +2177,7 @@ static void unqueue_me_pi(struct futex_q *q)
  * private futexes.
  */
 static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
-                               struct task_struct *newowner)
+               struct task_struct *newowner)
 {
        u32 newtid = task_pid_vnr(newowner) | FUTEX_WAITERS;
        struct futex_pi_state *pi_state = q->pi_state;
@@ -2323,40 +2349,83 @@ out:
  * @q:         the futex_q to queue up on
  * @timeout:   the prepared hrtimer_sleeper, or null for no timeout
  */
-static void futex_wait_queue_me(struct futex_hash_bucket *hb, struct futex_q *q,
-                               struct hrtimer_sleeper *timeout)
+static int futex_wait_queue_me(struct futex_hash_bucket *hb, struct futex_q *q,
+               struct hrtimer_sleeper *timeout,int ops)
 {
+       struct spin_key sk;
+       _spin_value *value = NULL;
+       _local_rq_t * l = NULL;
+       int counter = 0;
+       int ret = 0;
+       if(current->tgroup_distributed == 1){
+               __spin_key_init(&sk);
+               getKey((unsigned long) current->uaddr, &sk,current->tgroup_home_id);
+               value = hashspinkey(&sk);
+               smp_rmb();
+               l= find_request_by_ops(0, current->uaddr, current->pid, &value->_lrq_head);
+       }
+
        /*
         * The task state is guaranteed to be set before another task can
         * wake it. set_current_state() is implemented using set_mb() and
         * queue_me() calls spin_unlock() upon completion, both serializing
         * access to the hash list and forcing another memory barrier.
         */
-       set_current_state(TASK_INTERRUPTIBLE);
-       queue_me(q, hb);
+       if(current->tgroup_distributed == 1 && l && l->wake_st == 1){
+               ret = 1;
+               printk(KERN_ALERT"unlock 1\n");
+               if (q->lock_ptr != NULL && spin_is_locked(q->lock_ptr)) {
+                       spin_unlock(&hb->lock);
+               }
+       }       
+       else{
+               set_current_state(TASK_INTERRUPTIBLE);
+               //server queued it for me if i am the main
+               if(ops != WAIT_MAIN)
+                       queue_me(q, hb);
+               else{
+                       printk(KERN_ALERT"unlock 2 ops{%d} \n",ops);
+
+                       if (q->lock_ptr != NULL && spin_is_locked(q->lock_ptr)) {
+                               spin_unlock(&hb->lock);
+                       }
 
-       /* Arm the timer */
-       if (timeout) {
-               hrtimer_start_expires(&timeout->timer, HRTIMER_MODE_ABS);
-               if (!hrtimer_active(&timeout->timer))
-                       timeout->task = NULL;
-       }
+               }
+
+               /* Arm the timer */
+               if (timeout) {
+                       hrtimer_start_expires(&timeout->timer, HRTIMER_MODE_ABS);
+                       if (!hrtimer_active(&timeout->timer))
+                               timeout->task = NULL;
+               }
 
-       /*
-        * If we have been removed from the hash list, then another task
-        * has tried to wake us, and we can skip the call to schedule().
-        */
-       if (likely(!plist_node_empty(&q->list))) {
                /*
-                * If the timer has already expired, current will already be
-                * flagged for rescheduling. Only call schedule if there
-                * is no timeout, or if it has yet to expire.
+                * If we have been removed from the hash list, then another task
+                * has tried to wake us, and we can skip the call to schedule().
                 */
-               if (!timeout || timeout->task){
-                       schedule();
+               if (likely(!plist_node_empty(&q->list))) {
+                       /*
+                        * If the timer has already expired, current will already be
+                        * flagged for rescheduling. Only call schedule if there
+                        * is no timeout, or if it has yet to expire.
+                        */
+                       if (!timeout || timeout->task){
+                               if(current->tgroup_distributed == 1 && l && l->wake_st == 1){   
+                                       ret = 1;
+                               }
+                               else{
+                                       current->futex_state = 1;
+                                       schedule();
+                               }
+                       }
                }
        }
+
+       if(current->tgroup_distributed == 1 && l)
+               find_and_delete_pid(current->pid, &value->_lrq_head);
+
        __set_current_state(TASK_RUNNING);
+       return ret;
 }
 
 /**
@@ -2377,7 +2446,7 @@ static void futex_wait_queue_me(struct futex_hash_bucket *hb, struct futex_q *q,
  * <1 - -EFAULT or -EWOULDBLOCK (uaddr does not contain val) and hb is unlocked
  */
 static int futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags,
-                          struct futex_q *q, struct futex_hash_bucket **hb, unsigned int fn_flag,u32 bitset)
+               struct futex_q *q, struct futex_hash_bucket **hb, unsigned int fn_flag,u32 bitset)
 {
        u32 uval;
        int ret;
@@ -2409,12 +2478,12 @@ retry:
                return ret;
 
 retry_private:
-       //printk(KERN_ALERT " %s: spinlock  futex_wait_setup shared{%d} \n",__func__,(flags & FLAGS_SHARED));
 
        if(current->tgroup_distributed  && !(fn_flag & FLAGS_REMOTECALL) && !(flags & FLAGS_SHARED)){
 #ifdef FUTEX_STAT
-                perf_bb = native_read_tsc();
+               perf_bb = native_read_tsc();
 #endif
+               current->uaddr = (unsigned long) uaddr;
                g_errno = global_queue_wait_lock(q, uaddr, *hb, fn_flag, val,
                                flags & FLAGS_SHARED, VERIFY_READ, bitset);
 #ifdef FUTEX_STAT
@@ -2425,12 +2494,12 @@ retry_private:
 #ifdef FUTEX_STAT
                        _wait_err++;
 #endif
-                           ret = g_errno;
-                           if( ret == -EFAULT)
-                           {
-                                FPRINTK(KERN_ALERT" client side efault fix up {%d} \n",fault_in_user_writeable(uaddr));
-                               
-                           }
+                       ret = g_errno;
+                       if( ret == -EFAULT)
+                       {
+                               FPRINTK(KERN_ALERT" client side efault fix up {%d} \n",fault_in_user_writeable(uaddr));
+
+                       }
 
                } else if (!g_errno) {  //no error => just queue it acquiring spinlock
                        //get the actual spinlock : Not necessary as we are alone
@@ -2508,60 +2577,60 @@ static void printPTE(u32 __user *uaddr) {
        pfn = pte_pfn(pte);
        FPRINTK(KERN_ALERT" cpu{%d} pte pfn : 0x{%lx}\n", smp_processor_id(), pfn);
 
-       exit:
+exit:
        FPRINTK("exit\n");
 }
 
 
 static void dump_regs(struct pt_regs* regs) {
-    unsigned long fs, gs;
-   FPRINTK(KERN_ALERT"DUMP REGS\n");
-    if(NULL != regs) {
-        FPRINTK(KERN_ALERT"r15{%lx}\n",regs->r15);
-        FPRINTK(KERN_ALERT"r14{%lx}\n",regs->r14);
-        FPRINTK(KERN_ALERT"r13{%lx}\n",regs->r13);
-        FPRINTK(KERN_ALERT"r12{%lx}\n",regs->r12);
-        FPRINTK(KERN_ALERT"r11{%lx}\n",regs->r11);
-        FPRINTK(KERN_ALERT"r10{%lx}\n",regs->r10);
-        FPRINTK(KERN_ALERT"r9{%lx}\n",regs->r9);
-        FPRINTK(KERN_ALERT"r8{%lx}\n",regs->r8);
-        FPRINTK(KERN_ALERT"bp{%lx}\n",regs->bp);
-        FPRINTK(KERN_ALERT"bx{%lx}\n",regs->bx);
-        FPRINTK(KERN_ALERT"ax{%lx}\n",regs->ax);
-        FPRINTK(KERN_ALERT"cx{%lx}\n",regs->cx);
-        FPRINTK(KERN_ALERT"dx{%lx}\n",regs->dx);
-        FPRINTK(KERN_ALERT"di{%lx}\n",regs->di);
-        FPRINTK(KERN_ALERT"orig_ax{%lx}\n",regs->orig_ax);
-        FPRINTK(KERN_ALERT"ip{%lx}\n",regs->ip);
-        FPRINTK(KERN_ALERT"cs{%lx}\n",regs->cs);
-        FPRINTK(KERN_ALERT"flags{%lx}\n",regs->flags);
-        FPRINTK(KERN_ALERT"sp{%lx}\n",regs->sp);
-        FPRINTK(KERN_ALERT"ss{%lx}\n",regs->ss);
-    }
-    rdmsrl(MSR_FS_BASE, fs);
-    rdmsrl(MSR_GS_BASE, gs);
-    FPRINTK(KERN_ALERT"fs{%lx}\n",fs);
-    FPRINTK(KERN_ALERT"gs{%lx}\n",gs);
-    FPRINTK(KERN_ALERT"REGS DUMP COMPLETE\n");
+       unsigned long fs, gs;
+       FPRINTK(KERN_ALERT"DUMP REGS\n");
+       if(NULL != regs) {
+               FPRINTK(KERN_ALERT"r15{%lx}\n",regs->r15);
+               FPRINTK(KERN_ALERT"r14{%lx}\n",regs->r14);
+               FPRINTK(KERN_ALERT"r13{%lx}\n",regs->r13);
+               FPRINTK(KERN_ALERT"r12{%lx}\n",regs->r12);
+               FPRINTK(KERN_ALERT"r11{%lx}\n",regs->r11);
+               FPRINTK(KERN_ALERT"r10{%lx}\n",regs->r10);
+               FPRINTK(KERN_ALERT"r9{%lx}\n",regs->r9);
+               FPRINTK(KERN_ALERT"r8{%lx}\n",regs->r8);
+               FPRINTK(KERN_ALERT"bp{%lx}\n",regs->bp);
+               FPRINTK(KERN_ALERT"bx{%lx}\n",regs->bx);
+               FPRINTK(KERN_ALERT"ax{%lx}\n",regs->ax);
+               FPRINTK(KERN_ALERT"cx{%lx}\n",regs->cx);
+               FPRINTK(KERN_ALERT"dx{%lx}\n",regs->dx);
+               FPRINTK(KERN_ALERT"di{%lx}\n",regs->di);
+               FPRINTK(KERN_ALERT"orig_ax{%lx}\n",regs->orig_ax);
+               FPRINTK(KERN_ALERT"ip{%lx}\n",regs->ip);
+               FPRINTK(KERN_ALERT"cs{%lx}\n",regs->cs);
+               FPRINTK(KERN_ALERT"flags{%lx}\n",regs->flags);
+               FPRINTK(KERN_ALERT"sp{%lx}\n",regs->sp);
+               FPRINTK(KERN_ALERT"ss{%lx}\n",regs->ss);
+       }
+       rdmsrl(MSR_FS_BASE, fs);
+       rdmsrl(MSR_GS_BASE, gs);
+       FPRINTK(KERN_ALERT"fs{%lx}\n",fs);
+       FPRINTK(KERN_ALERT"gs{%lx}\n",gs);
+       FPRINTK(KERN_ALERT"REGS DUMP COMPLETE\n");
 }
 
 //static
 int futex_wait(u32 __user *uaddr, unsigned int flags, u32 val,
-                     ktime_t *abs_time, u32 bitset, unsigned int fn_flag)
+               ktime_t *abs_time, u32 bitset, unsigned int fn_flag)
 {
 
 #ifdef FUTEX_STAT
-        unsigned long long wait_aa,wait_bb,wait_cc;
-       if(current->tgroup_distributed){
-       wait_aa = native_read_tsc();
-       _wait_cnt++;
-       }
+       unsigned long long wait_aa,wait_bb,wait_cc;
+       if(current->tgroup_distributed){
+               wait_aa = native_read_tsc();
+               _wait_cnt++;
+       }
 #endif
        struct hrtimer_sleeper timeout, *to = NULL;
        struct restart_block *restart;
        struct futex_hash_bucket *hb;
        struct futex_q q = futex_q_init;
-       int ret;
+       int ret,retf;
        int sig;
 
        struct task_struct *t=current;
@@ -2572,7 +2641,7 @@ int futex_wait(u32 __user *uaddr, unsigned int flags, u32 val,
 
        FPRINTK(KERN_ALERT "FUTEX_WAIT:current {%pB} pid{%d} uaddr{%lx} get_user{%d} comm{%s}  syscall{%d} cpu{%d}\n",(void*) &bp,current->pid,uaddr,x,current->comm,fn_flag,smp_processor_id());
 
-//     printPTE(uaddr);
+       //      printPTE(uaddr);
        if (!bitset)
                return -EINVAL;
        q.bitset = bitset;
@@ -2581,39 +2650,38 @@ int futex_wait(u32 __user *uaddr, unsigned int flags, u32 val,
                to = &timeout;
 
                hrtimer_init_on_stack(&to->timer, (flags & FLAGS_CLOCKRT) ?
-                                     CLOCK_REALTIME : CLOCK_MONOTONIC,
-                                     HRTIMER_MODE_ABS);
+                               CLOCK_REALTIME : CLOCK_MONOTONIC,
+                               HRTIMER_MODE_ABS);
                hrtimer_init_sleeper(to, current);
                hrtimer_set_expires_range_ns(&to->timer, *abs_time,
-                                            current->timer_slack_ns);
+                               current->timer_slack_ns);
        }
 
 retry:
 
        FPRINTK(KERN_ALERT "%s:wait before task {%d} rep_rem {%d}  uaddr{%lx}\ value{%d} disp{%d}\n",__func__,
-               t->pid, t->tgroup_distributed, uaddr, x,current->return_disposition);
+                       t->pid, t->tgroup_distributed, uaddr, x,current->return_disposition);
        /*
         * Prepare to wait on uaddr. On success, holds hb lock and increments
         * q.key refs.
         */
-        /*if((strcmp("cond",current->comm) == 0) || (strcmp("bar",current->comm) == 0)){
-       printk(KERN_ALERT"%s: distributed{%d} cpu{%d} pid {%d} uaddr{%d} \n",__func__,current->tgroup_distributed,smp_processor_id(),current->pid,uaddr);
-       }*/
        ret = futex_wait_setup(uaddr, val, flags, &q, &hb,fn_flag,bitset);
-       
-       if (ret)
+
+       if (ret !=0 && ret != WAIT_MAIN)
                goto out;
 
 
        /* queue_me and wait for wakeup, timeout, or a signal. */
-       futex_wait_queue_me(hb, &q, to);
-
+       retf = futex_wait_queue_me(hb, &q, to, ret);
        /* If we were woken (and unqueued), we succeeded, whatever. */
-       ret = 0;
-
        /* unqueue_me() drops q.key ref */
-       if (!unqueue_me(&q))
-               goto out;
+       if(ret != WAIT_MAIN  ){
+               if(retf == 0 ){
+                       if (!unqueue_me(&q))
+                               goto out;
+               }
+       }
+
        ret = -ETIMEDOUT;
        if (to && !to->task)
                goto out;
@@ -2634,7 +2702,7 @@ retry:
        restart->fn = futex_wait_restart;
        restart->futex.uaddr = uaddr;
        restart->futex.val = val;
-         restart->futex.time = abs_time->tv64;
+       restart->futex.time = abs_time->tv64;
        restart->futex.bitset = bitset;
        restart->futex.flags = flags | FLAGS_HAS_TIMEOUT;
 
@@ -2647,76 +2715,74 @@ out:
        }
 #ifdef FUTEX_STAT
        if(current->tgroup_distributed){
-       wait_bb = native_read_tsc();
-       _wait += wait_bb - wait_aa ;
+               wait_bb = native_read_tsc();
+               _wait += wait_bb - wait_aa ;
        }
 #endif
        FPRINTK(KERN_DEBUG " %s:exit {%d}\n",__func__,current->pid);
        return ret;
 }
 int print_wait_perf(){
-printk(KERN_ALERT"%s: cpu{%d} pid{%d} tgid{%d} counter{%d} errors{%d} wait time {%llu}",
-               __func__,
-               smp_processor_id(),
-               current->pid,
-               current->tgroup_home_id,
-               _wait_cnt,
-               _wait_err,
-               _wait);
-_wait_err = 0;
-_wait = 0;
-_wait_cnt = 0;
+       printk(KERN_ALERT"%s: cpu{%d} pid{%d} tgid{%d} counter{%d} errors{%d} wait time {%llu}",
+                       __func__,
+                       smp_processor_id(),
+                       current->pid,
+                       current->tgroup_home_id,
+                       _wait_cnt,
+                       _wait_err,
+                       _wait);
+       _wait_err = 0;
+       _wait = 0;
+       _wait_cnt = 0;
 }
 
 int print_wake_perf(){
-printk(KERN_ALERT"%s: cpu{%d} pid{%d} tgid{%d} counter{%d} errors{%d} wake time {%llu}",
-               __func__,
-               smp_processor_id(),
-               current->pid,
-               current->tgroup_home_id,
-               _wake_cnt,
-               _wake_err,
-               _wake);
-_wake_err = 0;
-_wake = 0;
-_wake_cnt = 0;
+       printk(KERN_ALERT"%s: cpu{%d} pid{%d} tgid{%d} counter{%d} errors{%d} wake time {%llu}",
+                       __func__,
+                       smp_processor_id(),
+                       current->pid,
+                       current->tgroup_home_id,
+                       _wake_cnt,
+                       _wake_err,
+                       _wake);
+       _wake_err = 0;
+       _wake = 0;
+       _wake_cnt = 0;
 }
 
 
 int print_wakeop_perf(){
-printk(KERN_ALERT"%s: cpu{%d} pid{%d} tgid{%d} counter{%d} errors{%d} wakeop time {%llu}",
-               __func__,
-               smp_processor_id(),
-               current->pid,
-               current->tgroup_home_id,
-               _wakeop_cnt,
-               _wakeop_err,
-               _wakeop);
-_wakeop_err = 0;
-_wakeop = 0;
-_wakeop_cnt = 0;
+       printk(KERN_ALERT"%s: cpu{%d} pid{%d} tgid{%d} counter{%d} errors{%d} wakeop time {%llu}",
+                       __func__,
+                       smp_processor_id(),
+                       current->pid,
+                       current->tgroup_home_id,
+                       _wakeop_cnt,
+                       _wakeop_err,
+                       _wakeop);
+       _wakeop_err = 0;
+       _wakeop = 0;
+       _wakeop_cnt = 0;
 }
 
 int print_requeue_perf(){
-printk(KERN_ALERT"%s: cpu{%d} pid{%d} tgid{%d} counter{%d} errors{%d} requeue time {%llu}",
-               __func__,
-               smp_processor_id(),
-               current->pid,
-               current->tgroup_home_id,
-               _requeue_cnt,
-               _requeue_err,
-               _requeue);
-_requeue_err = 0;
-_requeue = 0;
-_requeue_cnt = 0;
+       printk(KERN_ALERT"%s: cpu{%d} pid{%d} tgid{%d} counter{%d} errors{%d} requeue time {%llu}",
+                       __func__,
+                       smp_processor_id(),
+                       current->pid,
+                       current->tgroup_home_id,
+                       _requeue_cnt,
+                       _requeue_err,
+                       _requeue);
+       _requeue_err = 0;
+       _requeue = 0;
+       _requeue_cnt = 0;
 }
 
 static long futex_wait_restart(struct restart_block *restart)
 {
        u32 __user *uaddr = restart->futex.uaddr;
        ktime_t t, *tp = NULL;
-       if(current->tgroup_distributed==1)
-               printk(KERN_ALERT"futex_restarted {%d} \n",uaddr);
        if (restart->futex.flags & FLAGS_HAS_TIMEOUT) {
                t.tv64 = restart->futex.time;
                tp = &t;
@@ -2724,7 +2790,7 @@ static long futex_wait_restart(struct restart_block *restart)
        restart->fn = do_no_restart_syscall;
 
        return (long)futex_wait(uaddr, restart->futex.flags,
-                               restart->futex.val, tp, restart->futex.bitset,FLAGS_SYSCALL);
+                       restart->futex.val, tp, restart->futex.bitset,FLAGS_SYSCALL);
 }
 
 
@@ -2735,7 +2801,7 @@ static long futex_wait_restart(struct restart_block *restart)
  * races the kernel might see a 0 value of the futex too.)
  */
 static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, int detect,
-                        ktime_t *time, int trylock)
+               ktime_t *time, int trylock)
 {
        struct hrtimer_sleeper timeout, *to = NULL;
        struct futex_hash_bucket *hb;
@@ -2748,7 +2814,7 @@ static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, int detect,
        if (time) {
                to = &timeout;
                hrtimer_init_on_stack(&to->timer, CLOCK_REALTIME,
-                                     HRTIMER_MODE_ABS);
+                               HRTIMER_MODE_ABS);
                hrtimer_init_sleeper(to, current);
                hrtimer_set_expires(&to->timer, *time);
        }
@@ -2764,23 +2830,23 @@ retry_private:
        ret = futex_lock_pi_atomic(uaddr, hb, &q.key, &q.pi_state, current, 0);
        if (unlikely(ret)) {
                switch (ret) {
-               case 1:
-                       /* We got the lock. */
-                       ret = 0;
-                       goto out_unlock_put_key;
-               case -EFAULT:
-                       goto uaddr_faulted;
-               case -EAGAIN:
-                       /*
-                        * Task is exiting and we just wait for the
-                        * exit to complete.
-                        */
-                       queue_unlock(&q, hb);
-                       put_futex_key(&q.key);
-                       cond_resched();
-                       goto retry;
-               default:
-                       goto out_unlock_put_key;
+                       case 1:
+                               /* We got the lock. */
+                               ret = 0;
+                               goto out_unlock_put_key;
+                       case -EFAULT:
+                               goto uaddr_faulted;
+                       case -EAGAIN:
+                               /*
+                                * Task is exiting and we just wait for the
+                                * exit to complete.
+                                */
+                               queue_unlock(&q, hb);
+                               put_futex_key(&q.key);
+                               cond_resched();
+                               goto retry;
+                       default:
+                               goto out_unlock_put_key;
                }
        }
 
@@ -2886,7 +2952,7 @@ retry:
         * anyone else up:
         */
        if (!(uval & FUTEX_OWNER_DIED) &&
-           cmpxchg_futex_value_locked(&uval, uaddr, vpid, 0))
+                       cmpxchg_futex_value_locked(&uval, uaddr, vpid, 0))
                goto pi_faulted;
        /*
         * Rare case: we managed to release the lock atomically,
@@ -2957,10 +3023,10 @@ pi_faulted:
  *  0 - no early wakeup detected
  * <0 - -ETIMEDOUT or -ERESTARTNOINTR
  */
-static inline
+       static inline
 int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
-                                  struct futex_q *q, union futex_key *key2,
-                                  struct hrtimer_sleeper *timeout)
+               struct futex_q *q, union futex_key *key2,
+               struct hrtimer_sleeper *timeout)
 {
        int ret = 0;
 
@@ -3031,8 +3097,8 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
  * <0 - On error
  */
 static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
-                                u32 val, ktime_t *abs_time, u32 bitset,
-                                u32 __user *uaddr2)
+               u32 val, ktime_t *abs_time, u32 bitset,
+               u32 __user *uaddr2)
 {
        struct hrtimer_sleeper timeout, *to = NULL;
        struct rt_mutex_waiter rt_waiter;
@@ -3048,11 +3114,11 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
        if (abs_time) {
                to = &timeout;
                hrtimer_init_on_stack(&to->timer, (flags & FLAGS_CLOCKRT) ?
-                                     CLOCK_REALTIME : CLOCK_MONOTONIC,
-                                     HRTIMER_MODE_ABS);
+                               CLOCK_REALTIME : CLOCK_MONOTONIC,
+                               HRTIMER_MODE_ABS);
                hrtimer_init_sleeper(to, current);
                hrtimer_set_expires_range_ns(&to->timer, *abs_time,
-                                            current->timer_slack_ns);
+                               current->timer_slack_ns);
        }
 
        /*
@@ -3079,7 +3145,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
                goto out_key2;
 
        /* Queue the futex_q, drop the hb lock, wait for wakeup. */
-       futex_wait_queue_me(hb, &q, to);
+       futex_wait_queue_me(hb, &q, to,0);
        spin_lock(&hb->lock);
        ret = handle_early_requeue_pi_wakeup(hb, &q, &key2, to);
        spin_unlock(&hb->lock);
@@ -3239,8 +3305,8 @@ SYSCALL_DEFINE3(get_robust_list, int, pid,
                }
                /* If victim is in same user_ns, then uids are comparable */
                if (cred->euid != pcred->euid &&
-                   cred->euid != pcred->uid &&
-                   !ns_capable(pcred->user->user_ns, CAP_SYS_PTRACE))
+                               cred->euid != pcred->uid &&
+                               !ns_capable(pcred->user->user_ns, CAP_SYS_PTRACE))
                        goto err_unlock;
 ok:
                head = p->robust_list;
@@ -3303,7 +3369,7 @@ retry:
                 * PI futexes happens in exit_pi_state():
                 */
                if (!pi && (uval & FUTEX_WAITERS))
-                       futex_wake(uaddr, 1, 1, FUTEX_BITSET_MATCH_ANY,FLAGS_SYSCALL, NULL);//modified
+               futex_wake(uaddr, 1, 1, FUTEX_BITSET_MATCH_ANY,FLAGS_SYSCALL, NULL);//modified
        }
        return 0;
 }
@@ -3312,8 +3378,8 @@ retry:
  * Fetch a robust-list pointer. Bit 0 signals PI futexes:
  */
 static inline int fetch_robust_entry(struct robust_list __user **entry,
-                                    struct robust_list __user * __user *head,
-                                    unsigned int *pi)
+               struct robust_list __user * __user *head,
+               unsigned int *pi)
 {
        unsigned long uentry;
 
@@ -3349,7 +3415,7 @@ void exit_robust_list(struct task_struct *curr)
         * sys_set_robust_list()):
         */
        if (fetch_robust_entry(&entry, &head->list.next, &pi))
-               return;
+       return;
        /*
         * Fetch the relative futex offset:
         */
@@ -3392,13 +3458,13 @@ void exit_robust_list(struct task_struct *curr)
 
        if (pending)
                handle_futex_death((void __user *)pending + futex_offset,
-                                  curr, pip);
+                               curr, pip);
 }
 
 long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
                u32 __user *uaddr2, u32 val2, u32 val3)
 {
-//     FPRINTK(KERN_ALERT "uaddr {%d} \n",uaddr);
+       //      FPRINTK(KERN_ALERT "uaddr {%d} \n",uaddr);
        int ret = -ENOSYS, cmd = op & FUTEX_CMD_MASK;
        unsigned int flags = 0;
        unsigned int fn_flags = 0;
@@ -3414,54 +3480,54 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
        }
 
        switch (cmd) {
-       case FUTEX_LOCK_PI:
-       case FUTEX_UNLOCK_PI:
-       case FUTEX_TRYLOCK_PI:
-       case FUTEX_WAIT_REQUEUE_PI:
-       case FUTEX_CMP_REQUEUE_PI:
-               if (!futex_cmpxchg_enabled)
-                       return -ENOSYS;
+               case FUTEX_LOCK_PI:
+               case FUTEX_UNLOCK_PI:
+               case FUTEX_TRYLOCK_PI:
+               case FUTEX_WAIT_REQUEUE_PI:
+               case FUTEX_CMP_REQUEUE_PI:
+                       if (!futex_cmpxchg_enabled)
+                               return -ENOSYS;
        }
 
        switch (cmd) {
-       case FUTEX_WAIT:
-               val3 = FUTEX_BITSET_MATCH_ANY;
-       case FUTEX_WAIT_BITSET:
-               ret = futex_wait(uaddr, flags, val, timeout, val3,fn_flags);
-               break;
-       case FUTEX_WAKE:
-               val3 = FUTEX_BITSET_MATCH_ANY;
-       case FUTEX_WAKE_BITSET:
-               ret = futex_wake(uaddr, flags, val, val3,fn_flags, NULL);
-               break;
-       case FUTEX_REQUEUE:
-               ret = futex_requeue(uaddr, flags, uaddr2, val, val2, NULL, 0,fn_flags, NULL);
-               break;
-       case FUTEX_CMP_REQUEUE:
-               ret = futex_requeue(uaddr, flags, uaddr2, val, val2, &val3, 0,fn_flags, NULL);
-               break;
-       case FUTEX_WAKE_OP:
-               ret = futex_wake_op(uaddr, flags, uaddr2, val, val2, val3,fn_flags, NULL);
-               break;
-       case FUTEX_LOCK_PI:
-               ret = futex_lock_pi(uaddr, flags, val, timeout, 0);
-               break;
-       case FUTEX_UNLOCK_PI:
-               ret = futex_unlock_pi(uaddr, flags);
-               break;
-       case FUTEX_TRYLOCK_PI:
-               ret = futex_lock_pi(uaddr, flags, 0, timeout, 1);
-               break;
-       case FUTEX_WAIT_REQUEUE_PI:
-               val3 = FUTEX_BITSET_MATCH_ANY;
-               ret = futex_wait_requeue_pi(uaddr, flags, val, timeout, val3,
-                                           uaddr2);
-               break;
-       case FUTEX_CMP_REQUEUE_PI:
-               ret = futex_requeue(uaddr, flags, uaddr2, val, val2, &val3, 1,fn_flags, NULL);
-               break;
-       default:
-               ret = -ENOSYS;
+               case FUTEX_WAIT:
+                       val3 = FUTEX_BITSET_MATCH_ANY;
+               case FUTEX_WAIT_BITSET:
+                       ret = futex_wait(uaddr, flags, val, timeout, val3,fn_flags);
+                       break;
+               case FUTEX_WAKE:
+                       val3 = FUTEX_BITSET_MATCH_ANY;
+               case FUTEX_WAKE_BITSET:
+                       ret = futex_wake(uaddr, flags, val, val3,fn_flags, NULL);
+                       break;
+               case FUTEX_REQUEUE:
+                       ret = futex_requeue(uaddr, flags, uaddr2, val, val2, NULL, 0,fn_flags, NULL);
+                       break;
+               case FUTEX_CMP_REQUEUE:
+                       ret = futex_requeue(uaddr, flags, uaddr2, val, val2, &val3, 0,fn_flags, NULL);
+                       break;
+               case FUTEX_WAKE_OP:
+                       ret = futex_wake_op(uaddr, flags, uaddr2, val, val2, val3,fn_flags, NULL);
+                       break;
+               case FUTEX_LOCK_PI:
+                       ret = futex_lock_pi(uaddr, flags, val, timeout, 0);
+                       break;
+               case FUTEX_UNLOCK_PI:
+                       ret = futex_unlock_pi(uaddr, flags);
+                       break;
+               case FUTEX_TRYLOCK_PI:
+                       ret = futex_lock_pi(uaddr, flags, 0, timeout, 1);
+                       break;
+               case FUTEX_WAIT_REQUEUE_PI:
+                       val3 = FUTEX_BITSET_MATCH_ANY;
+                       ret = futex_wait_requeue_pi(uaddr, flags, val, timeout, val3,
+                                       uaddr2);
+                       break;
+               case FUTEX_CMP_REQUEUE_PI:
+                       ret = futex_requeue(uaddr, flags, uaddr2, val, val2, &val3, 1,fn_flags, NULL);
+                       break;
+               default:
+                       ret = -ENOSYS;
        }
        return ret;
 }
@@ -3475,10 +3541,42 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val,
        ktime_t t, *tp = NULL;
        u32 val2 = 0;
        int cmd = op & FUTEX_CMD_MASK;
-
+       int retn=0;
+rcu_read_lock();
+       current->futex_state = 1;
+rcu_read_unlock();
+       smp_mb();
+       if((current->migration_state == 1 || current->represents_remote ==1)){
+          printk(KERN_ALERT"in the middle of migartion  pid{%d} ops{%d} cmd{%d}\n",current->pid,op,cmd);
+        struct spin_key sk;
+        __spin_key_init(&sk);
+
+        //Get the local mapped value for the key (TGID|Uaddr)
+        getKey(uaddr, &sk,current->tgroup_home_id);
+        _spin_value *value = hashspinkey(&sk);
+
+       _mig_value * val = (_mig_value*) kmalloc(sizeof(_mig_value),GFP_ATOMIC); 
+       val->pid = current->pid;
+        val->uaddr = uaddr;
+        val->ops = cmd;
+       val->request_time = CURRENT_TIME;
+       val->response_time = val->request_time;
+       val->served = 0;
+        value->mig_st = val;
+
+        __set_task_state(current,TASK_UNINTERRUPTIBLE);
+         int (*ip_func) (struct task_struct*);
+         shadow_return_check(current);
+         //current->thread.ip = (unsigned long) ip_func;
+       }
+
+      if(current->tgroup_distributed ==1 || (strcmp(current->comm,"is-gomp")==0)){
+                         printk(KERN_ALERT"%s: uadd{%lx} op{%d} utime{%lx} uaddr2{%lx} pid{%d} smp{%d}tg{%d}  state{%d}\n",__func__,uaddr,op,utime,uaddr2,current->pid,smp_processor_id(),current->tgroup_distributed,current->represents_remote);
+                        }
+  
        if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI ||
-                     cmd == FUTEX_WAIT_BITSET ||
-                     cmd == FUTEX_WAIT_REQUEUE_PI)) {
+                               cmd == FUTEX_WAIT_BITSET ||
+                               cmd == FUTEX_WAIT_REQUEUE_PI)) {
                if (copy_from_user(&ts, utime, sizeof(ts)) != 0)
                        return -EFAULT;
                if (!timespec_valid(&ts))
@@ -3494,12 +3592,19 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val,
         * number of waiters to wake in 'utime' if cmd == FUTEX_WAKE_OP.
         */
        if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE ||
-           cmd == FUTEX_CMP_REQUEUE_PI || cmd == FUTEX_WAKE_OP)
+                       cmd == FUTEX_CMP_REQUEUE_PI || cmd == FUTEX_WAKE_OP)
                val2 = (u32) (unsigned long) utime;
 
-       return do_futex(uaddr, op, val, tp, uaddr2, val2, val3);
-}
+       retn = do_futex(uaddr, op, val, tp, uaddr2, val2, val3);
 
+           if( (strcmp(current->comm,"is-gomp")==0))
+                           printk(KERN_ALERT"%s: END +++++++++++++pid{%d} retn{%d} uaddr{%lx}\n",__func__,current->pid,retn,uaddr);
+rcu_read_lock();
+        current->futex_state = 0;
+rcu_read_unlock();
+
+       return retn;    
+}
 static int __init futex_init(void)
 {
        u32 curval;
index cb2c6e6..ad5058f 100644 (file)
@@ -24,7 +24,7 @@
 #include <popcorn/pid.h>
 #include <asm/page_types.h>
 #include <linux/mmu_context.h>
-
+#include <linux/list.h>
 #include "futex_remote.h"
 #define ENOTINKRN 999
 #define MODULE "GRQ-"
 #include <asm/tlbflush.h>
 #include <asm/cacheflush.h>
 
+#define STAT
+//#undef STAT
+#define WAIT_MAIN 99
+
 #define FUTEX_REMOTE_VERBOSE 0 
 #if FUTEX_REMOTE_VERBOSE
 #define FRPRINTK(...) printk(__VA_ARGS__)
 #define FRPRINTK(...) ;
 #endif
 
-#ifdef CONFIG_PPC_BOOK3E_64
-#define is_kernel_addr(x)       ((x) >= 0x8000000000000000ul)
-#else
-#define is_kernel_addr(x)       ((x) >= PAGE_OFFSET)
-#endif
 
 #define GENERAL_SPIN_LOCK(x) spin_lock(x)
 #define GENERAL_SPIN_UNLOCK(x) spin_unlock(x)
@@ -61,9 +60,11 @@ static volatile unsigned int finish_work = 0;
 static DECLARE_WAIT_QUEUE_HEAD(wait_);
 static DECLARE_WAIT_QUEUE_HEAD(resume_);
 
+#ifdef STAT
 static atomic_t progress = ATOMIC_INIT(0);
-
 static unsigned int counter = 0;
+#endif
+
 extern struct list_head pfn_list_head;
 
 extern int unqueue_me(struct futex_q *q);
@@ -71,10 +72,16 @@ extern int unqueue_me(struct futex_q *q);
 
 
 void _spin_key_init (struct spin_key *st) {
-       st->_tgid = 0;
-       st->_uaddr = 0;
-       st->offset = 0;
- }
+       st->_tgid = 0;
+       st->_uaddr = 0;
+       st->offset = 0;
+}
+static const _global_value gvp_init = {
+       .thread_group_leader = NULL,
+       .worker_task = NULL,
+       .free = 0,
+       .global_wq = NULL
+};
 
 
 //void _spin_key_init (struct spin_key *st);
@@ -188,6 +195,7 @@ int find_and_delete_inc(int pid, struct list_head *head) {
                        return 1;
                }
        }
+       return 0;
 }
 
 pte_t *do_page_walk(unsigned long address) {
@@ -219,7 +227,7 @@ pte_t *do_page_walk(unsigned long address) {
        pte = ptep;
 
        return (pte_t*) pte;
-       exit: return NULL;
+exit: return NULL;
 }
 
 
@@ -268,6 +276,7 @@ int global_futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake,
        struct mm_struct *cmm = NULL;
        struct task_struct *temp;
        int ret;
+       int found = 0;
        FRPRINTK(KERN_ALERT "%s: entry response {%d} uaddr{%lx} comm{%s} flags{%u} uaddr2{%lx} \n",__func__,pid,uaddr,current->comm,flags,uaddr2);
        if (!bitset)
                return -EINVAL;
@@ -276,17 +285,23 @@ int global_futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake,
        _spin_key_init(&sk);
 
        tsk = gettask(pid);
-       //printk(KERN_ALERT"%s: rem pid{%d} tsk{%d}\n",__func__,pid,(!tsk) ? 0 : 1);
 
        if(!tsk){       
                goto out;
        }
+       if(uaddr2 & (PAGE_SIZE-1)){
+               unsigned long add = uaddr;
+               add -= add % PAGE_SIZE;
+               uaddr2 = add + (uaddr2 & (PAGE_SIZE-1));
+       }
 
        getKey((uaddr2 == 0) ? (unsigned long)uaddr : (unsigned long) uaddr2, &sk,(!tsk)?current->tgroup_home_id:tsk->tgroup_home_id);
-       
+
        _spin_value *value = hashspinkey(&sk);
        _local_rq_t * l= find_request_by_pid(pid, &value->_lrq_head);
-       
+
+       smp_mb();
+
        FRPRINTK(KERN_ALERT "%s: set wake up \n",__func__);
 
        ret = get_futex_key_tsk((uaddr2 == 0) ? uaddr : (u32 __user*) uaddr2,(flags & FLAGS_SHARED), &key, VERIFY_READ, tsk);
@@ -310,14 +325,24 @@ int global_futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake,
                                        //spin_unlock(&this->lock_ptr);
                                }
                                FRPRINTK(KERN_ALERT"%s:call wake futex \n",__func__);
+                               //l->_st = 1;
+                               found = 1;
                                wake_futex(this);
                        }
                }
 
        }
+       if(!found && l &&  l->status == DONE){
+               if(tsk && tsk->state != TASK_RUNNING) {
+                       printk(KERN_ALERT"TASK_NOT RUN\n");
+                       get_task_struct(tsk);   wake_up_state(tsk,TASK_NORMAL); put_task_struct(tsk);
+               }
+       }
+
+
        spin_unlock(&hb->lock);
        put_futex_key(&key);
-       
+
 out:
 
 
@@ -328,14 +353,14 @@ out:
 
 
 int fix_user_page(u32 __user * uaddr,struct task_struct *tsk){
-struct mm_struct *mm=tsk->mm;
-int ret;
+       struct mm_struct *mm=tsk->mm;
+       int ret;
 
-down_read(&mm->mmap_sem);
-ret =fixup_user_fault(tsk,mm, (unsigned long) uaddr, FAULT_FLAG_WRITE| FAULT_FLAG_NONLINEAR | FAULT_FLAG_MKWRITE |FAULT_FLAG_KILLABLE );
-up_read(&mm->mmap_sem);
+       down_read(&mm->mmap_sem);
+       ret =fixup_user_fault(tsk,mm, (unsigned long) uaddr, FAULT_FLAG_WRITE| FAULT_FLAG_NONLINEAR | FAULT_FLAG_MKWRITE |FAULT_FLAG_KILLABLE );
+       up_read(&mm->mmap_sem);
 
-return ret < 0 ? ret :0;
+       return ret < 0 ? ret :0;
 
 }
 int global_futex_wait(unsigned long uaddr, unsigned int flags, u32 val,
@@ -346,27 +371,28 @@ int global_futex_wait(unsigned long uaddr, unsigned int flags, u32 val,
        struct task_struct *rem_struct = NULL;
        struct futex_q *q = (struct futex_q *) kmalloc(sizeof(struct futex_q),
                        GFP_ATOMIC);
-       struct page *pages;
-       
+
        q->key = FUTEX_KEY_INIT;
        q->bitset = FUTEX_BITSET_MATCH_ANY;
        q->rem_pid = -1;
        q->req_addr = 0;
        q->rem_requeue_key = FUTEX_KEY_INIT;
+       q->pi_state = NULL;
+       q->rt_waiter = NULL;
 
        u32 uval;
        int ret;
        int sig;
        int prio;
 
-       q->bitset = bitset;
+       q->bitset = (!bitset) ? FUTEX_BITSET_MATCH_ANY : bitset;
 
        //start wait setup
 retry:
        ret = get_futex_key_tsk((u32 __user *)uaddr, flags & FLAGS_SHARED, &q->key, VERIFY_READ, tsk);
        FRPRINTK(KERN_ALERT "%s: pid origin {%s} _cpu{%d} uaddr{%lx} uval{%d} ret{%d} \n ",__func__,tsk->comm,smp_processor_id(),uaddr,val,ret);
        if (unlikely(ret != 0))
-          return ret;
+               return ret;
 
 
 retry_private:
@@ -380,34 +406,34 @@ fault:
        ret = get_futex_value_locked(&uval, (u32 __user *)uaddr);
 
        if (ret) {
-                       spin_unlock(&hb->lock);
-                       FRPRINTK(KERN_ALERT "%s:after spin unlock ret{%d} uval{%lx}\n ",__func__,ret,uval);
+               spin_unlock(&hb->lock);
+               FRPRINTK(KERN_ALERT "%s:after spin unlock ret{%d} uval{%lx}\n ",__func__,ret,uval);
 
-                       if(ret == -EFAULT){
-                               flush_cache_mm(tsk->mm);
-                               ret = fix_user_page((u32 __user *)uaddr,tsk);                           
-                               flush_tlb_mm(tsk->mm);
-                       }
+               if(ret == -EFAULT){
+                       flush_cache_mm(tsk->mm);
+                       ret = fix_user_page((u32 __user *)uaddr,tsk);                           
+                       flush_tlb_mm(tsk->mm);
+               }
 
-                       ret = get_user(uval, (u32 __user *)uaddr);
+               ret = get_user(uval, (u32 __user *)uaddr);
 
-                       if (ret){
-                               FRPRINTK(KERN_ALERT "%s:after get user out ret{%d} uval{%lx}\n ",__func__,ret,uval);
-                               goto out;
-                       }
+               if (ret){
+                       FRPRINTK(KERN_ALERT "%s:after get user out ret{%d} uval{%lx}\n ",__func__,ret,uval);
+                       goto out;
+               }
 
-                       unuse_mm(tsk->mm);
+               unuse_mm(tsk->mm);
 
-                       if (!(flags & FLAGS_SHARED))
-                               goto retry_private;
+               if (!(flags & FLAGS_SHARED))
+                       goto retry_private;
 
-                       put_futex_key(&q->key);
-                       goto retry;
+               put_futex_key(&q->key);
+               goto retry;
        }
 
        if (uval != val) {
-                       spin_unlock(&hb->lock);
-                       ret = -EWOULDBLOCK;
+               spin_unlock(&hb->lock);
+               ret = -EWOULDBLOCK;
        }
 
        if(ret)
@@ -415,26 +441,30 @@ fault:
 
        //queue me for origin node shall be made by the local thread itself
        rem_struct =  pid_task(find_vpid(rem), PIDTYPE_PID);
-       if(rem_struct){
-               FRPRINTK(KERN_ALERT "%s:local request unlock\n ",__func__);
-               spin_unlock(&hb->lock);
-               goto out;
-       }
        //no need to schedule as the rem_struct will be waiting for the ack from server.
 
 
        //queue me the dummy node for remote
        prio = 100; //min(current->normal_prio, MAX_RT_PRIO);
        plist_node_init(&q->list, prio);
+       if(!rem_struct){
+               q->task = NULL;
+               q->rem_pid = rem;
+               ret = 0;
+       }
+       else{
+               get_task_struct(rem_struct);
+               q->task = rem_struct;
+               q->rem_pid = -1;
+               ret = WAIT_MAIN;
+               put_task_struct(rem_struct);
+       }
        plist_add(&q->list, &hb->chain);
-
-                       q->task = NULL;
-                       q->rem_pid = rem;
+       smp_mb();
 
        FRPRINTK(KERN_ALERT "%s:global request unlock queue me \n ",__func__);
        spin_unlock(&hb->lock);
 
-       //no need to schedule as the remote will schedule();
 
 out:
        if(ret){
@@ -452,110 +482,130 @@ out:
 void global_worher_fn(struct work_struct* work) {
        global_request_work_t* w = (global_request_work_t*) work;
 
-        _global_rq *this, *next;
+       _global_rq *this, *next;
        struct task_struct *tsk = current;
        struct task_struct *task, *g;
        struct mm_struct *cmm = NULL;
-       int null_flag = 0;
-       int exch_value;
-       static unsigned has_work =0;
-       unsigned long flags =0;
+       int _return = 0;
        //Set task struct for the worker
        worker_pid = current->pid;
 
        FRPRINTK(KERN_ALERT "%s:GRQ started {%s}\n",__func__,current->comm);
 
-        this = (_global_rq*) w->gq;
-
-       has_work = 0;
-       FRPRINTK(KERN_ALERT "%s:retry has_work{%d} \n",__func__,has_work);
+       this = (_global_rq*) w->gq;
 
 
        struct spin_key sk;
        _spin_key_init(&sk);
 
-               if (this->ops == WAKE_OPS) //process wake request from GRQ
-               {
-                       _remote_wakeup_request_t* msg = (_remote_wakeup_request_t*) &this->wakeup;
-                       int ret =0;
-
-                       getKey(msg->uaddr, &sk,msg->tghid);
-                       _spin_value *value = hashspinkey(&sk);
-                       FRPRINTK(KERN_ALERT"%s:wake--current msg pid{%d} msg->ticket{%d} \n", __func__,msg->pid,msg->ticket);
-
-                       if (msg->rflag == 0 || (msg->fn_flag & FLAGS_ORIGINCALL)) {
-
-                                       tsk = gettask(msg->tghid);
-
-                                       msg->fn_flag |= FLAGS_REMOTECALL;
-
-                                       if (msg->fn_flag & FLAGS_WAKECALL)
-                                               ret = futex_wake(msg->uaddr, msg->flags, msg->nr_wake, msg->bitset,
-                                                               msg->fn_flag,tsk);
-
-                                       else if (msg->fn_flag & FLAGS_REQCALL)
-                                               ret = futex_requeue(msg->uaddr, msg->flags, (unsigned long)  (msg->uaddr2 & ((1600*PAGE_SIZE)-1)), msg->nr_wake,
-                                                               msg->nr_wake2, &(msg->cmpval),0, msg->fn_flag,tsk);
-
-                                       else if (msg->fn_flag & FLAGS_WAKEOPCALL)
-                                               ret = futex_wake_op((u32 __user*)msg->uaddr, msg->flags,(u32 __user*)(msg->uaddr2 & ((1600*PAGE_SIZE)-1)), msg->nr_wake,
-                                                               msg->nr_wake2, msg->cmpval, msg->fn_flag,tsk);
+       if (this->ops == WAKE_OPS) //process wake request from GRQ
+       {
+               _remote_wakeup_request_t* msg = (_remote_wakeup_request_t*) &this->wakeup;
+               int ret =0;
+
+               getKey(msg->uaddr, &sk,msg->tghid);
+               _spin_value *value = hashspinkey(&sk);
+               if(value->mig_st != NULL){
+                       if(value->mig_st->uaddr == msg->uaddr && value->mig_st->ops == FUTEX_WAIT){
+                               value->mig_st->response_time = CURRENT_TIME;
+                               value->mig_st->served = 1; 
+                       }
+               }
 
-                               }
-                               FRPRINTK(KERN_ALERT "%s:after setting mm to NULL\n",__func__);
+               FRPRINTK(KERN_ALERT"%s:wake--current msg pid{%d} msg->ticket{%d} fn{%d} uaddr{%lx} uaddr2{%lx} \n", __func__,msg->pid,msg->ticket,(msg->fn_flag & FLAGS_WAKECALL) ? 1 : ((msg->fn_flag & FLAGS_REQCALL) ? 2 : 4),msg->uaddr,msg->uaddr2);
 
-                                       //send ticket
-                                       _remote_wakeup_response_t send_tkt;
-                                       send_tkt.header.type = PCN_KMSG_TYPE_REMOTE_IPC_FUTEX_WAKE_RESPONSE;
-                                       send_tkt.header.prio = PCN_KMSG_PRIO_NORMAL;
-                                       send_tkt.errno =ret ;
-                                       send_tkt.request_id=msg->ticket;
-                                       send_tkt.uaddr = msg->uaddr;
-                                       send_tkt.rem_pid = msg->pid;
-                                       FRPRINTK(KERN_ALERT "send ticket to wake request {%d} msg->pid{%d} msg->uaddr{%lx} \n",send_tkt.rem_pid,msg->pid,msg->uaddr);
-                                       pcn_kmsg_send(ORIG_NODE(send_tkt.rem_pid), (struct pcn_kmsg_message*) (&send_tkt));
+               if (msg->rflag == 0 || (msg->fn_flag & FLAGS_ORIGINCALL)) {
 
+                       tsk = gettask(msg->tghid);
 
-               } else if(this->ops == WAIT_OPS){ //wait request
+                       current->surrogate = msg->tghid;
 
-                       _remote_key_request_t* msg = (_remote_key_request_t*) &this->wait;
-                       int ret =0 ;
+                       msg->fn_flag |= FLAGS_REMOTECALL;
 
-                       getKey(msg->uaddr, &sk,msg->tghid);
-                       _spin_value *value = hashspinkey(&sk);
+                       if (msg->fn_flag & FLAGS_WAKECALL)
+                               ret = futex_wake(msg->uaddr, msg->flags, msg->nr_wake, msg->bitset,
+                                               msg->fn_flag,tsk);
 
-                       FRPRINTK(KERN_ALERT"%s:wait --current msg pid{%d} msg->ticket{%d} \n", __func__,msg->pid,msg->ticket);
+                       else if (msg->fn_flag & FLAGS_REQCALL)
+                               ret = futex_requeue(msg->uaddr, msg->flags, (unsigned long) msg->uaddr2, msg->nr_wake,
+                                               msg->nr_wake2, &(msg->cmpval),0, msg->fn_flag,tsk);
 
-                       tsk = gettask(msg->tghid);
-                       if (msg->fn_flags & FLAGS_ORIGINCALL) {
-                               msg->fn_flags |= FLAGS_REMOTECALL;
-                               ret = global_futex_wait(msg->uaddr, msg->flags, msg->val, 0, 0, msg->pid, tsk,
-                                               msg->fn_flags);
-                       } else
-                               ret = global_futex_wait(msg->uaddr, msg->flags, msg->val, 0, 0, msg->pid, tsk,
-                                                       msg->fn_flags);
+                       else if (msg->fn_flag & FLAGS_WAKEOPCALL)
+                               ret = futex_wake_op((u32 __user*)msg->uaddr, msg->flags,(u32 __user*)(msg->uaddr2), msg->nr_wake,
+                                               msg->nr_wake2, msg->cmpval, msg->fn_flag,tsk);
 
+               }
+               FRPRINTK(KERN_ALERT "%s:after setting mm to NULL\n",__func__);
+
+               //send ticket
+               _remote_wakeup_response_t send_tkt;
+               send_tkt.header.type = PCN_KMSG_TYPE_REMOTE_IPC_FUTEX_WAKE_RESPONSE;
+               send_tkt.header.prio = PCN_KMSG_PRIO_NORMAL;
+               send_tkt.errno =ret ;
+               send_tkt.request_id=msg->ticket;
+               send_tkt.uaddr = msg->uaddr;
+               send_tkt.rem_pid = msg->pid;
+               FRPRINTK(KERN_ALERT "send ticket to wake request {%d} msg->pid{%d} msg->uaddr{%lx} \n",send_tkt.rem_pid,msg->pid,msg->uaddr);
+               _return = pcn_kmsg_send(ORIG_NODE(send_tkt.rem_pid), (struct pcn_kmsg_message*) (&send_tkt));
+               if(_return == -1)
+                       printk(KERN_ALERT"%s: wake resp message not sent\n",__func__);
+
+       } else if(this->ops == WAIT_OPS){ //wait request
+
+               _remote_key_request_t* msg = (_remote_key_request_t*) &this->wait;
+               int ret =0 ;
+
+               getKey(msg->uaddr, &sk,msg->tghid);
+               _spin_value *value = hashspinkey(&sk);
+               if(value->mig_st != NULL){
+                       if(value->mig_st->uaddr == msg->uaddr){
+                               printk(KERN_ALERT"mig value exist for wait ops");
+                               if(value->mig_st->served && ((value->mig_st->response_time.tv_sec+value->mig_st->response_time.tv_nsec) > (value->mig_st->request_time.tv_sec+value->mig_st->request_time.tv_nsec))){
+                                       printk(KERN_ALERT"already woken up");
+                                       kfree(value->mig_st);
+                                       ret = -EAGAIN;
+                                       goto resp;
+                               }
+                       }
+               }
+               FRPRINTK(KERN_ALERT"%s:wait --current msg pid{%d} msg->ticket{%d} msg->uadr{%lx} \n", __func__,msg->pid,msg->ticket,msg->uaddr);
+
+               tsk = gettask(msg->tghid);
+               current->surrogate = msg->tghid;
+
+               if (msg->fn_flags & FLAGS_ORIGINCALL) {
+                       msg->fn_flags |= FLAGS_REMOTECALL;
+                       ret = global_futex_wait(msg->uaddr, msg->flags, msg->val, 0, msg->bitset, msg->pid, tsk,
+                                       msg->fn_flags);
+               } else{
+                       ret = global_futex_wait(msg->uaddr, msg->flags, msg->val, 0, msg->bitset, msg->pid, tsk,
+                                       msg->fn_flags);
+               }
 
-                                       //send response
-                                       _remote_key_response_t send_tkt;
-                                       send_tkt.header.type = PCN_KMSG_TYPE_REMOTE_IPC_FUTEX_KEY_RESPONSE;
-                                       send_tkt.header.prio = PCN_KMSG_PRIO_NORMAL;
-                                       send_tkt.errno =ret ;
-                                       send_tkt.request_id=msg->ticket;
-                                       send_tkt.uaddr = msg->uaddr;
-                                       send_tkt.rem_pid = msg->pid;
-                                       FRPRINTK(KERN_ALERT "send ticket to wait request {%d} msg->pid{%d} msg->uaddr{%lx} \n",send_tkt.rem_pid,msg->pid,msg->uaddr);
-                                       pcn_kmsg_send(ORIG_NODE(send_tkt.rem_pid), (struct pcn_kmsg_message*) (&send_tkt));
+               //send response
+resp:          ;
+               _remote_key_response_t send_tkt;
+               send_tkt.header.type = PCN_KMSG_TYPE_REMOTE_IPC_FUTEX_KEY_RESPONSE;
+               send_tkt.header.prio = PCN_KMSG_PRIO_NORMAL;
+               send_tkt.errno =ret ;
+               send_tkt.request_id=msg->ticket;
+               send_tkt.uaddr = msg->uaddr;
+               send_tkt.rem_pid = msg->pid;
+               FRPRINTK(KERN_ALERT "send ticket to wait request {%d} msg->pid{%d} msg->uaddr{%lx} \n",send_tkt.rem_pid,msg->pid,msg->uaddr);
+               _return = pcn_kmsg_send(ORIG_NODE(send_tkt.rem_pid), (struct pcn_kmsg_message*) (&send_tkt));
 
 
+               if(_return == -1)
+                       printk(KERN_ALERT"%s: wake resp message not sent\n",__func__);
 
-                       }
+       }
 cleanup:
-               //Delete the entry
-               counter++;
-               FRPRINTK(KERN_ALERT "done iteration moving the head cnt{%d} counter{%d} \n",this->cnt,counter);
-
-               kfree(this);
+#ifdef STAT
+       counter++;
+       FRPRINTK(KERN_ALERT "done iteration moving the head cnt{%d} counter{%d} \n",this->cnt,counter);
+#endif
+       //Delete the entry
+       kfree(this);
 
 
 exit:
@@ -566,13 +616,13 @@ exit:
 static int handle_remote_futex_wake_response(struct pcn_kmsg_message* inc_msg) {
        _remote_wakeup_response_t* msg = (_remote_wakeup_response_t*) inc_msg;
        preempt_disable();
-       
+
        FRPRINTK(KERN_ALERT"%s: response {%d} \n",
                        __func__, msg->errno);
        struct task_struct *p =  pid_task(find_vpid(msg->rem_pid), PIDTYPE_PID);
-        
+
        if(!p)
-          goto out;
+               goto out;
 
        get_task_struct(p);
 
@@ -585,13 +635,13 @@ static int handle_remote_futex_wake_response(struct pcn_kmsg_message* inc_msg) {
 
 
        _local_rq_t *ptr = set_err_request(msg->request_id,msg->errno, &value->_lrq_head);
-       // smp_wmb();
-       FRPRINTK(KERN_ALERT"%s: errno{%d} p->tgp(%d} \n",__func__,msg->errno,p->tgroup_home_id);
+       FRPRINTK(KERN_ALERT"%s: errno{%d} p->tgp(%d} ptr{%p} done{%d}\n",__func__,msg->errno,p->tgroup_home_id,ptr,(!ptr) ? 10 : ptr->status);
 
+       smp_wmb();
        put_task_struct(p);
 
 out:   pcn_kmsg_free_msg(inc_msg);
-       
+
        preempt_enable();
 
        return 0;
@@ -602,70 +652,102 @@ static int handle_remote_futex_wake_request(struct pcn_kmsg_message* inc_msg) {
        _remote_wakeup_request_t* msg = (_remote_wakeup_request_t*) inc_msg;
        _remote_wakeup_response_t response;
        struct task_struct *tsk = current;
-       struct task_struct *task, *g;
-       struct mm_struct *cmm = NULL;
-       int null_flag = 0;
-       _global_value * gvp;
+       _global_bkt * gbp;
+       _global_value * gvp,*this,*next;
+       struct list_head *hd;
+       int present =0;
 
-       unsigned long flags;
+#ifdef STAT
        atomic_inc(&progress);
-
+#endif
        FRPRINTK(KERN_ALERT"%s: request -- entered task comm{%s} pid{%d} msg->fn_flag{%lx} msg-flags{%lx}\n", __func__,tsk->comm,tsk->pid,msg->fn_flag,msg->flags);
-       FRPRINTK(KERN_ALERT"%s: msg: uaddr {%lx}  uaddr2{%lx} ticket {%d} tghid{%d} bitset {%u} rflag{%d} pid{%d} ifn_flags{%lx}\n",
-                       __func__,msg->uaddr,(msg->uaddr2 & (PAGE_SIZE-1)),msg->ticket,msg->tghid,msg->bitset,msg->rflag,msg->pid,msg->fn_flag);
+       FRPRINTK(KERN_ALERT"%s: msg: uaddr {%lx} ud{%lx}  uaddr2{%lx} ticket {%d} tghid{%d} bitset {%u} rflag{%d} pid{%d} ifn_flags{%lx}\n",
+                       __func__,msg->uaddr,msg->uaddr2,(msg->uaddr2 & (PAGE_SIZE-1)),msg->ticket,msg->tghid,msg->bitset,msg->rflag,msg->pid,msg->fn_flag);
 
        // Finish constructing response
        response.header.type = PCN_KMSG_TYPE_REMOTE_IPC_FUTEX_WAKE_RESPONSE;
        response.header.prio = PCN_KMSG_PRIO_NORMAL;
        tsk =  pid_task(find_vpid(msg->tghid), PIDTYPE_PID);
-        
-       if(( (msg->fn_flag < FLAGS_MAX) && (msg->fn_flag & FLAGS_ORIGINCALL)) || msg->rflag == 0){
-       GENERAL_SPIN_LOCK(&access_global_value_table);
 
-       gvp = hashgroup(tsk);
-       if (!gvp->free) { //futex_wake is the first one
-               //scnprintf(gvp->name, sizeof(gvp->name), MODULE);
-               gvp ->free =1;
+       if(!tsk){
+               FRPRINTK("%s: no task found {%d} \n",__func__,msg->tghid);
+               goto out;
        }
-       FRPRINTK(KERN_ALERT"%s: wake gvp free \n", __func__);
-       gvp->global_wq = grq;// create_singlethread_workqueue(gvp->name);
-       gvp->thread_group_leader = tsk;
-       global_request_work_t* back_work = NULL;
-       // Spin up bottom half to process this event
-       back_work = (global_request_work_t*) kmalloc(sizeof(global_request_work_t),
-                               GFP_ATOMIC);
-       if (back_work) {
-                       INIT_WORK((struct work_struct* )back_work, global_worher_fn);
 
-                       FRPRINTK(KERN_ALERT"%s: set up head\n", __func__);
-                       
-                       back_work->lock = &gvp->lock; 
-                       
-                       _global_rq *trq = (_global_rq *) kmalloc(sizeof(_global_rq), GFP_ATOMIC);                       
-                       memcpy(&trq->wakeup, msg, sizeof(_remote_wakeup_request_t));
-                       trq->ops = WAKE_OPS;
-                       trq->cnt = atomic_read(&progress);
-                       //smp_mb();barrier()i;
+       if(( (msg->fn_flag < FLAGS_MAX) && (msg->fn_flag & FLAGS_ORIGINCALL)) || msg->rflag == 0){
+               //GENERAL_SPIN_LOCK(&access_global_value_table);
 
-                       back_work->gq = trq;
-                       queue_work(gvp->global_wq, (struct work_struct*) back_work);
+               gbp = hashgroup(tsk);
+
+               GENERAL_SPIN_LOCK(&gbp->lock);
+               hd = &gbp->link;
+               list_for_each_entry_safe(this, next, hd, _link_head){
+                       if(this->thread_group_leader->pid == tsk->pid){
+                               present =1;
+                               gvp = this; 
+                               break;
+                       }
+               }
+               if(present == 0 && gvp == NULL){
+                       gvp = &gvp_init;
+                       INIT_LIST_HEAD(&gvp->_link_head);
+                       list_add(&gvp->_link_head, &gbp->link);
+                       smp_mb();
+               }
+               if(gvp != NULL){
+
+                       if (!gvp->free) { //futex_wake is the first one
+                               //scnprintf(gvp->name, sizeof(gvp->name), MODULE);
+                               gvp ->free =1;
+                       }
+                       FRPRINTK(KERN_ALERT"%s: wake gvp free \n", __func__);
+                       gvp->global_wq = grq;// create_singlethread_workqueue(gvp->name);
+                       gvp->thread_group_leader = tsk;
+                       global_request_work_t* back_work = NULL;
+                       // Spin up bottom half to process this event
+                       back_work = (global_request_work_t*) kmalloc(sizeof(global_request_work_t),
+                                       GFP_ATOMIC);
+                       if (back_work) {
+                               INIT_WORK((struct work_struct* )back_work, global_worher_fn);
+
+                               FRPRINTK(KERN_ALERT"%s: set up head\n", __func__);
+
+                               //back_work->lock = &gvp->lock; 
+
+                               _global_rq *trq = (_global_rq *) kmalloc(sizeof(_global_rq), GFP_ATOMIC);                       
+                               memcpy(&trq->wakeup, msg, sizeof(_remote_wakeup_request_t));
+
+                               if(msg->uaddr2 & (PAGE_SIZE-1)){
+                                       unsigned long add = msg->uaddr;
+                                       add -= msg->uaddr % PAGE_SIZE;
+                                       trq->wakeup.uaddr2 = add + (msg->uaddr2 & (PAGE_SIZE-1));
+                               }   
+                               trq->ops = WAKE_OPS;
+#ifdef STAT    
+                               trq->cnt = atomic_read(&progress);
+#else
+                               trq->cnt = 0;
+#endif
+
+                               back_work->gq = trq;
+                               queue_work(gvp->global_wq, (struct work_struct*) back_work);
+                       }
+                       gvp->worker_task = back_work;
                }
-       gvp->worker_task = back_work;
-       GENERAL_SPIN_UNLOCK(&access_global_value_table);
+               GENERAL_SPIN_UNLOCK(&gbp->lock);
 
 
-       FRPRINTK(KERN_ALERT"%s: ERROR msg ticket{%d}\n", __func__,msg->ticket);
+               FRPRINTK(KERN_ALERT"%s: ERROR msg ticket{%d}\n", __func__,msg->ticket);
 
-       //Check whether the request is asking for ticket or holding the ticket?
+               //Check whether the request is asking for ticket or holding the ticket?
                //if not holding the ticket add to the tail of Global request queue.
                //if not holding the ticket add to the tail of Global request queue.
        }
        else {
-                FRPRINTK(KERN_ALERT"need to wake_st uaddr2{%lx} \n",(msg->uaddr2 & ((1600*PAGE_SIZE)-1)));
                global_futex_wake(msg->uaddr, msg->flags, msg->nr_wake, msg->bitset,
-                                                               msg->rflag,(unsigned long) (msg->uaddr2 & ((1600*PAGE_SIZE)-1)));
+                               msg->rflag,(unsigned long) (msg->uaddr2 & (PAGE_SIZE-1)));
        }
-       
+out:
        pcn_kmsg_free_msg(inc_msg);
 
        return 0;
@@ -677,7 +759,6 @@ int remote_futex_wakeup(u32 __user *uaddr, unsigned int flags, int nr_wake,
 
        int res = 0;
        int cpu = 0;
-       struct page *page, *page_head;
        _remote_wakeup_request_t *request = kmalloc(sizeof(_remote_wakeup_request_t),
                        GFP_ATOMIC);
        FRPRINTK(KERN_ALERT"%s: -- entered whos calling{%s} \n", __func__,current->comm);
@@ -701,18 +782,17 @@ int remote_futex_wakeup(u32 __user *uaddr, unsigned int flags, int nr_wake,
        request->ops = 1;
        request->ticket = 1; //wake operations are always loack removing operations
 
-       int x = 0, y = 0;
-       int wake = 0, woke = 0, nw = 0, bs = 0;
+       int x = 0;
 
-       FRPRINTK(KERN_ALERT" %s: pid{%d}  cpu{%d} rflag{%d} uaddr{%lx} get_user{%d} fn_flags{%lx}\n ",__func__,
-                       current->pid,smp_processor_id(),rflag,uaddr,x,fn_flags);
+       FRPRINTK(KERN_ALERT" %s: pid{%d}  cpu{%d} rflag{%d} uaddr{%lx} uaddr2{%lx} fn_flags{%lx}\n ",__func__,
+                       current->pid,smp_processor_id(),rflag,uaddr,uaddr2,fn_flags);
 
        //      dump_regs(task_pt_regs(current));
 
        // Send response
-               if (rflag) {
+       if (rflag) {
                request->fn_flag &= 1;
-               FRPRINTK(KERN_ALERT "%s: sending to remote node {%d} flag{%lx}\n",__func__, ORIG_NODE(rflag),request->fn_flag);
+               FRPRINTK(KERN_ALERT "%s: sending to remote node {%d} flag{%lx} uaddr2{%lx}\n",__func__, ORIG_NODE(rflag),request->fn_flag,request->uaddr2);
                res = pcn_kmsg_send(ORIG_NODE(rflag), (struct pcn_kmsg_message*) (request));// no need for remote lock to wake up
        }
 
@@ -724,15 +804,19 @@ out:
 static int handle_remote_futex_key_response(struct pcn_kmsg_message* inc_msg) {
        _remote_key_response_t* msg = (_remote_key_response_t*) inc_msg;
        preempt_disable();
-       
+
        FRPRINTK(KERN_ALERT"%s: response to revoke wait request as origin is dead {%d} \n",
                        __func__,msg->errno);
 
        struct task_struct *p =  pid_task(find_vpid(msg->rem_pid), PIDTYPE_PID);
 
-       if(!p)
+
+       if(!p){
+               FRPRINTK("%s: no task found {%d} \n",__func__,msg->rem_pid);
                goto out;
-       
+       }
+
+
        get_task_struct(p);
 
        struct spin_key sk;
@@ -743,18 +827,18 @@ static int handle_remote_futex_key_response(struct pcn_kmsg_message* inc_msg) {
        // update the local value status to has ticket
 
        FRPRINTK(KERN_ALERT"%s:  value {%d}  p->tgroup_home_id{%d}  \n",
-                                       __func__, value->_st,p->tgroup_home_id);
+                       __func__, value->_st,p->tgroup_home_id);
        //smp_wmb();
 
        _local_rq_t *ptr = set_err_request(msg->request_id,msg->errno, &value->_lrq_head);
-       
+
 
        put_task_struct(p);
 
 out:   pcn_kmsg_free_msg(inc_msg);
-       
+
        preempt_enable();
-       
+
        return 0;
 }
 
@@ -764,10 +848,14 @@ static int handle_remote_futex_key_request(struct pcn_kmsg_message* inc_msg) {
        _remote_key_response_t response;
        struct task_struct *tsk;
        int res;
-       _global_value * gvp;
+       _global_bkt * gbp;
+       _global_value * gvp,*this,*next;
+       struct list_head *hd;
+       int present =0;
        unsigned long flags;
-        atomic_inc(&progress);
-
+#ifdef STAT
+       atomic_inc(&progress);
+#endif
        FRPRINTK(KERN_ALERT"%s: request -- entered whos calling{%s} \n", __func__,current->comm);
        FRPRINTK(KERN_ALERT"%s: msg: uaddr {%lx} flags {%lx} val{%d}  pid{%d}  fn_flags{%lx} ticket{%d}\n",
                        __func__,msg->uaddr,msg->flags,msg->val,msg->pid,msg->fn_flags,msg->ticket);
@@ -777,19 +865,42 @@ static int handle_remote_futex_key_request(struct pcn_kmsg_message* inc_msg) {
        response.header.prio = PCN_KMSG_PRIO_NORMAL;
 
        tsk =  pid_task(find_vpid(msg->tghid), PIDTYPE_PID);
+       if(!tsk){
+               FRPRINTK("%s: no task found {%d} \n",__func__,msg->tghid);
+               goto out;
+       }
 
-       GENERAL_SPIN_LOCK(&access_global_value_table);
-       gvp = hashgroup(tsk);
-       if(!gvp->free) {
-               gvp->free =1;
+       //GENERAL_SPIN_LOCK(&access_global_value_table);
+       //gvp = hashgroup(tsk);
+       gbp = hashgroup(tsk);
+
+       GENERAL_SPIN_LOCK(&gbp->lock);
+       hd = &gbp->link;
+       list_for_each_entry_safe(this, next, hd, _link_head){
+               if(this->thread_group_leader->pid == tsk->pid){
+                       present =1;
+                       gvp = this;
+                       break;
+               }
+       }
+       if(present == 0 && gvp == NULL){
+               gvp = &gvp_init;
+               INIT_LIST_HEAD(&gvp->_link_head);
+               list_add(&gvp->_link_head, &gbp->link);
+               smp_mb();
        }
+       if(gvp != NULL){
+
+               if(!gvp->free) {
+                       gvp->free =1;
+               }
                //futex wait is the first global request
-       FRPRINTK(KERN_ALERT"%s: wait gvp free \n", __func__);
-//     scnprintf(gvp->name, sizeof(gvp->name), MODULE);
+               FRPRINTK(KERN_ALERT"%s: wait gvp free \n", __func__);
+               //      scnprintf(gvp->name, sizeof(gvp->name), MODULE);
 
-       gvp->global_wq = grq;//create_singlethread_workqueue(gvp->name);
-       gvp->thread_group_leader = tsk;
-       global_request_work_t* back_work = NULL;
+               gvp->global_wq = grq;//create_singlethread_workqueue(gvp->name);
+               gvp->thread_group_leader = tsk;
+               global_request_work_t* back_work = NULL;
 
                // Spin up bottom half to process this event
                back_work = (global_request_work_t*) kmalloc(sizeof(global_request_work_t),
@@ -797,43 +908,90 @@ static int handle_remote_futex_key_request(struct pcn_kmsg_message* inc_msg) {
                if (back_work) {
                        INIT_WORK((struct work_struct* )back_work, global_worher_fn);
                        FRPRINTK(KERN_ALERT"%s: set up head\n", __func__);
-                       back_work->lock = &gvp->lock; // , sizeof(spinlock_t));
-                       
+                       //back_work->lock = &gvp->lock; // , sizeof(spinlock_t));
+
                        _global_rq *trq = (_global_rq *) kmalloc(sizeof(_global_rq), GFP_ATOMIC);
                        memcpy(&trq->wait, msg, sizeof(_remote_key_request_t));
+#ifdef STAT
                        trq->cnt =atomic_read(&progress);
+#else
+                       trq->cnt = 0;
+#endif
+
                        trq->ops = WAIT_OPS;
 
                        back_work->gq = trq;
                        FRPRINTK(KERN_ALERT"%s: wait token aqc trq->wait.ticket{%d} cnt{%d}\n", __func__,trq->wait.ticket,trq->cnt);
-                       
+
                        queue_work(grq, (struct work_struct*) back_work);
                }
-       gvp->worker_task = back_work;//pid_task(find_vpid(worker_pid), PIDTYPE_PID);
-       GENERAL_SPIN_UNLOCK(&access_global_value_table);
-
+               gvp->worker_task = back_work;//pid_task(find_vpid(worker_pid), PIDTYPE_PID);
+       }
+       GENERAL_SPIN_UNLOCK(&gbp->lock);
+       //GENERAL_SPIN_UNLOCK(&access_global_value_table);
+out:
        pcn_kmsg_free_msg(inc_msg);
 
        return 0;
 }
 
+extern int remote_kill_pid_info(int kernel, int sig, pid_t pid,
+               struct siginfo *info);
+
+static void zap_remote_threads(struct task_struct *tsk){
+       struct task_struct *tg_itr;
+       tg_itr = tsk;
+       while_each_thread(tsk,tg_itr){
+               if(tg_itr->tgroup_distributed == 1 && tg_itr->tgroup_home_id != tg_itr->pid && tg_itr->represents_remote == 1) {
+                       siginfo_t info;
+                       memset(&info, 0, sizeof info);
+                       info.si_signo = SIGKILL;
+                       info.si_code = 1;
+                       info.si_pid = task_pid_vnr(current);
+                       info.si_uid = current_uid();
+                       remote_kill_pid_info(ORIG_NODE(tg_itr->next_pid), SIGKILL, tg_itr->next_pid,&info);             
+               }
+       }
+}
+
+
 int futex_global_worker_cleanup(struct task_struct *tsk){
 
 
-   if(tsk->tgroup_distributed && tsk->pid == tsk->tgroup_home_id){
-   _global_value * gvp = hashgroup(tsk);
-    FRPRINTK(KERN_INFO "GVP EXISTS{%s} tgid{%d} pid{%d} \n",tsk->comm,tsk->tgroup_home_id,tsk->pid);
+       if(tsk->tgroup_distributed && tsk->pid == tsk->tgroup_home_id){
+               if(tsk->return_disposition != 0) {
+                       dump_stack();
+                       printk(KERN_ALERT"remote zoombie kill needed\n");
+                       zap_remote_threads(tsk); 
+               }
 
-       if(gvp != NULL){
+               _global_bkt * gbp;
+               _global_value * gvp,*this,*next;
+               struct list_head *hd;
+               gbp = hashgroup(tsk);
+
+               GENERAL_SPIN_LOCK(&gbp->lock);
+               hd = &gbp->link;
+               list_for_each_entry_safe(gvp, next, hd, _link_head){
+                       if(gvp->thread_group_leader->pid == tsk->pid){
+
+                               FRPRINTK(KERN_INFO "GVP EXISTS{%s} tgid{%d} pid{%d} \n",tsk->comm,tsk->tgroup_home_id,tsk->pid);
+
+                               if(gvp != NULL){
+
+                                       FRPRINTK(KERN_INFO"Inside GVP");
+                                       gvp->thread_group_leader = NULL;
+                                       gvp->free = 0;
+                                       gvp->global_wq = NULL;
+                                       gvp->worker_task =NULL;
+                                       FRPRINTK(KERN_INFO "cleaned up \n");
+                               }
+                               break;
+                       }
+               }
+               GENERAL_SPIN_UNLOCK(&gbp->lock);
 
-               FRPRINTK(KERN_INFO"Inside GVP");
-               gvp->thread_group_leader = NULL;
-               gvp->free = 0;
-               gvp->global_wq = NULL;
-               gvp->worker_task =NULL;
-               FRPRINTK(KERN_INFO "cleaned up \n");
        }
-    }
 
        return 0;
 }
index d753d25..70f8038 100644 (file)
@@ -13,7 +13,7 @@ union futex_key; //forward decl for futex_remote.h
 #include <linux/slab.h>
 #include <linux/syscalls.h>
 #include <popcorn/global_spinlock.h>
-
+#include <popcorn/remote_pfn.h>
 #include <linux/pcn_kmsg.h>
 
 #define FLAGS_SYSCALL          8
@@ -26,8 +26,8 @@ union futex_key; //forward decl for futex_remote.h
 DEFINE_SPINLOCK(request_queue_lock);
 
 //hash buckets
- _spin_value spin_bucket[1<<_SPIN_HASHBITS];
- _global_value global_bucket[1<<_SPIN_HASHBITS];
+_spin_value spin_bucket[1<<_SPIN_HASHBITS];
+_global_bkt global_bucket[1<<_SPIN_HASHBITS];
 
 #define GENERAL_SPIN_LOCK(x,f) spin_lock_irqsave(x,f)
 #define GENERAL_SPIN_UNLOCK(x,f) spin_unlock_irqrestore(x,f)
@@ -39,119 +39,174 @@ DEFINE_SPINLOCK(request_queue_lock);
 #define GSPRINTK(...) ;
 #endif
 //extern functions
- extern struct vm_area_struct * getVMAfromUaddr(unsigned long uaddr);
- extern pte_t *do_page_walk(unsigned long address);
- extern  int find_kernel_for_pfn(unsigned long addr, struct list_head *head);
-
- _local_rq_t * add_request_node(int request_id, pid_t pid, struct list_head *head) {
-
-        unsigned long f;
-        GENERAL_SPIN_LOCK(&request_queue_lock,f);
-        _local_rq_t *Ptr = (_local_rq_t *) kmalloc(
-                       sizeof(_local_rq_t), GFP_ATOMIC);
-
-       memset(Ptr, 0, sizeof(_local_rq_t));
-       Ptr->_request_id = request_id;
-       Ptr->status = IDLE;
-       Ptr->wake_st = 0;
-       Ptr->_pid = pid;
-       init_waitqueue_head(&Ptr->_wq);
-       INIT_LIST_HEAD(&Ptr->lrq_member);
-       list_add(&Ptr->lrq_member, head);
-        GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
-
-       return Ptr;
- }
-
- int find_and_delete_request(int request_id, struct list_head *head) {
-
-       struct list_head *iter;
-       _local_rq_t *objPtr;
+extern struct vm_area_struct * getVMAfromUaddr(unsigned long uaddr);
+extern pte_t *do_page_walk(unsigned long address);
+extern  int find_kernel_for_pfn(unsigned long addr, struct list_head *head);
+
+_local_rq_t * add_request_node(int request_id, pid_t pid, struct list_head *head) {
+
+       unsigned long f;
+       GENERAL_SPIN_LOCK(&request_queue_lock,f);
+       _local_rq_t *Ptr = (_local_rq_t *) kmalloc(
+                       sizeof(_local_rq_t), GFP_ATOMIC);
+
+       memset(Ptr, 0, sizeof(_local_rq_t));
+       Ptr->_request_id = request_id;
+       Ptr->status = IDLE;
+       Ptr->wake_st = 0;
+       Ptr->_pid = pid;
+       init_waitqueue_head(&Ptr->_wq);
+       INIT_LIST_HEAD(&Ptr->lrq_member);
+       list_add(&Ptr->lrq_member, head);
+       GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
+
+       return Ptr;
+}
+
+int find_and_delete_request(int request_id, struct list_head *head) {
+
+       struct list_head *iter;
+       _local_rq_t *objPtr;
+       unsigned long f;
+       GENERAL_SPIN_LOCK(&request_queue_lock,f);
+       list_for_each(iter, head)
+       {
+               objPtr = list_entry(iter, _local_rq_t, lrq_member);
+               if (objPtr->_request_id == request_id) {
+                       list_del(&objPtr->lrq_member);
+                       kfree(objPtr);
+                       GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
+                       return 1;
+               }
+       }
+       GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
+}
+
+
+int find_and_delete_pid(int pid, struct list_head *head) {
+
+       struct list_head *iter;
+       _local_rq_t *objPtr;
+       unsigned long f;
+       GENERAL_SPIN_LOCK(&request_queue_lock,f);
+       list_for_each(iter, head)
+       {
+               objPtr = list_entry(iter, _local_rq_t, lrq_member);
+               if (objPtr->_pid == pid) {
+                       list_del(&objPtr->lrq_member);
+                       kfree(objPtr);
+                       GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
+                       return 1;
+               }
+       }
+       GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
+}
+
+_local_rq_t * find_request(int request_id, struct list_head *head) {
+
+       struct list_head *iter;
+       _local_rq_t *objPtr;
        unsigned long f;
-        GENERAL_SPIN_LOCK(&request_queue_lock,f);
-       list_for_each(iter, head)
-       {
-               objPtr = list_entry(iter, _local_rq_t, lrq_member);
-               if (objPtr->_request_id == request_id) {
-                       list_del(&objPtr->lrq_member);
-                       kfree(objPtr);
-                        GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
-                       return 1;
-               }
-       }
-        GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
- }
-
-
- _local_rq_t * find_request(int request_id, struct list_head *head) {
-
-       struct list_head *iter;
-       _local_rq_t *objPtr;
+       GENERAL_SPIN_LOCK(&request_queue_lock,f);
+       list_for_each(iter, head)
+       {
+               objPtr = list_entry(iter, _local_rq_t, lrq_member);
+               if (objPtr->_request_id == request_id) {
+                       GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
+                       return objPtr;
+               }
+       }
+       GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
+       return NULL;
+}
+
+_local_rq_t * set_err_request(int request_id, int err, struct list_head *head) {
+
+       struct list_head *iter;
+       _local_rq_t *objPtr;
        unsigned long f;
-        GENERAL_SPIN_LOCK(&request_queue_lock,f);
-       list_for_each(iter, head)
-       {
-               objPtr = list_entry(iter, _local_rq_t, lrq_member);
-               if (objPtr->_request_id == request_id) {
-                       GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
-                       return objPtr;
-               }
-       }
-        GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
-       return NULL;
- }
-
- _local_rq_t * set_err_request(int request_id, int err, struct list_head *head) {
-
-struct list_head *iter;
-_local_rq_t *objPtr;
-unsigned long f;
-        GENERAL_SPIN_LOCK(&request_queue_lock,f);
-       list_for_each(iter, head)
-       {
+       GENERAL_SPIN_LOCK(&request_queue_lock,f);
+       list_for_each(iter, head)
+       {
                objPtr = list_entry(iter, _local_rq_t, lrq_member);
                if (objPtr->_request_id == request_id) {
                        objPtr->status =DONE;
                        objPtr->errno = err;
                        wake_up_interruptible(&objPtr->_wq);
-                       GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
-                       return objPtr;
-               }
-       }
-        GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
-       return NULL;
+                       GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
+                       return objPtr;
+               }
+       }
+       GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
+       return NULL;
 }
 
- _local_rq_t *find_request_by_pid(pid_t pid, struct list_head *head) {
+_local_rq_t *find_request_by_pid(pid_t pid, struct list_head *head) {
 
-       struct list_head *iter;
-       _local_rq_t *objPtr;
+       struct list_head *iter;
+       _local_rq_t *objPtr;
        unsigned long f;
-        GENERAL_SPIN_LOCK(&request_queue_lock,f);
-       list_for_each(iter, head)
-       {
-               objPtr = list_entry(iter, _local_rq_t, lrq_member);
-               if (objPtr->_pid == pid) {
-                       objPtr->wake_st =1; //Set wake state as ON
-                       GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
-                       return objPtr;
-               }
-       }
-        GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
-       return NULL;
- }
+       GENERAL_SPIN_LOCK(&request_queue_lock,f);
+       list_for_each(iter, head)
+       {
+               objPtr = list_entry(iter, _local_rq_t, lrq_member);
+               if (objPtr->_pid == pid && objPtr->ops == 0) {
+                       GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
+                       return objPtr;
+               }
+       }
+       GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
+       return NULL;
+}
 
 
 
 
- inline void spin_key_init (struct spin_key *st) {
-       st->_tgid = 0;
-       st->_uaddr = 0;
-       st->offset = 0;
-  }
+_local_rq_t *find_request_by_ops(int ops, unsigned long uaddr,pid_t pid, struct list_head *head) {
 
+       struct list_head *iter;
+       _local_rq_t *objPtr;
+       unsigned long f;
+       GENERAL_SPIN_LOCK(&request_queue_lock,f);
+       list_for_each(iter, head)
+       {
+               objPtr = list_entry(iter, _local_rq_t, lrq_member);
+               if (objPtr->ops == 0 && objPtr->uaddr == uaddr && objPtr->_pid == pid) {
+                       GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
+                       return objPtr;
+               }
+       }
+       GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
+       return NULL;
+}
+
+_local_rq_t *set_wake_request_by_pid(pid_t pid, struct list_head *head) {
+
+       struct list_head *iter;
+       _local_rq_t *objPtr;
+       unsigned long f;
+       GENERAL_SPIN_LOCK(&request_queue_lock,f);
+       list_for_each(iter, head)
+       {
+               objPtr = list_entry(iter, _local_rq_t, lrq_member);
+               if (objPtr->_pid == pid) {
+                       objPtr->wake_st =1; //Set wake state as ON
+                       GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
+                       return objPtr;
+               }
+       }
+       GENERAL_SPIN_UNLOCK(&request_queue_lock,f);
+       return NULL;
+}
 
- //Populate spin key from uaddr
+inline void spin_key_init (struct spin_key *st) {
+       st->_tgid = 0;
+       st->_uaddr = 0;
+       st->offset = 0;
+}
+
+
+//Populate spin key from uaddr
 int getKey(unsigned long uaddr, _spin_key *sk, pid_t tgid)
 {
        unsigned long address = (unsigned long)uaddr;
@@ -173,50 +228,47 @@ _spin_value *hashspinkey(_spin_key *sk)
 }
 
 //to get the global worker and global request queue
-_global_value *hashgroup(struct task_struct *group_pid)
+_global_bkt *hashgroup(struct task_struct *group_pid)
 {
        struct task_struct *tsk =NULL;
        tsk= group_pid;
-       pagefault_disable();
        u32 hash = sp_hashfn(tsk->pid,0);
-       pagefault_enable();
        return &global_bucket[hash];
 }
 // Perform global spin lock
-int global_spinlock(unsigned long uaddr,futex_common_data_t *_data,_spin_value * value,_local_rq_t *rq_ptr,int localticket_value)
+       int global_spinlock(unsigned long uaddr,futex_common_data_t *_data,_spin_value * value,_local_rq_t *rq_ptr,int localticket_value)
 __releases(&value->_sp)
 {
        int res = 0;
        int cpu=0;
        unsigned int flgs;
 
-        _remote_key_request_t* wait_req= (_remote_key_request_t*) kmalloc(sizeof(_remote_key_request_t),
-                               GFP_ATOMIC);
-        _remote_wakeup_request_t *wake_req = (_remote_wakeup_request_t*) kmalloc(sizeof(_remote_wakeup_request_t),
-                               GFP_ATOMIC);
+       _remote_key_request_t* wait_req= (_remote_key_request_t*) kmalloc(sizeof(_remote_key_request_t),
+                       GFP_ATOMIC);
+       _remote_wakeup_request_t *wake_req = (_remote_wakeup_request_t*) kmalloc(sizeof(_remote_wakeup_request_t),
+                       GFP_ATOMIC);
 
        //Prepare request
        if(_data->ops==WAIT_OPS){
 
-//     printk(KERN_ALERT"%s: request -- entered whos calling{%s} \n", __func__,current->comm);
-       GSPRINTK(KERN_ALERT"%s:  uaddr {%lx}  pid{%d} current->tgroup_home_id{%d}\n",                           __func__,uaddr,current->pid,current->tgroup_home_id);
+               GSPRINTK(KERN_ALERT"%s:  uaddr {%lx}  pid{%d} current->tgroup_home_id{%d}\n",__func__,uaddr,current->pid,current->tgroup_home_id);
 
-       // Finish constructing response
-       wait_req->header.type = PCN_KMSG_TYPE_REMOTE_IPC_FUTEX_KEY_REQUEST;
-       wait_req->header.prio = PCN_KMSG_PRIO_NORMAL;
+               // Finish constructing response
+               wait_req->header.type = PCN_KMSG_TYPE_REMOTE_IPC_FUTEX_KEY_REQUEST;
+               wait_req->header.prio = PCN_KMSG_PRIO_NORMAL;
 
-       wait_req->ops = WAIT_OPS;
-       wait_req->rw = _data->rw;
-       wait_req->val = _data->val;
+               wait_req->ops = WAIT_OPS;
+               wait_req->rw = _data->rw;
+               wait_req->val = _data->val;
 
-       wait_req->uaddr = (unsigned long) uaddr;
-       wait_req->tghid = current->tgroup_home_id;
-       wait_req->bitset = _data->bitset;
-       wait_req->pid = current->pid;
-       wait_req->fn_flags = _data->fn_flag;
-       wait_req->flags = _data->flags;
+               wait_req->uaddr = (unsigned long) uaddr;
+               wait_req->tghid = current->tgroup_home_id;
+               wait_req->bitset = _data->bitset;
+               wait_req->pid = current->pid;
+               wait_req->fn_flags = _data->fn_flag;
+               wait_req->flags = _data->flags;
 
-       wait_req->ticket = localticket_value;//GET_TOKEN; //set the request has no ticket
+               wait_req->ticket = localticket_value;//GET_TOKEN; //set the request has no ticket
        }
        else{
                wake_req->header.type = PCN_KMSG_TYPE_REMOTE_IPC_FUTEX_WAKE_REQUEST;
@@ -251,116 +303,48 @@ __releases(&value->_sp)
        struct vm_area_struct *vma;
        vma = getVMAfromUaddr(uaddr);
        if (vma != NULL && current->executing_for_remote && (vma->vm_flags & VM_PFNMAP)) {
-                               if(_data->ops==WAIT_OPS){
-                                       wait_req->fn_flags |= FLAGS_REMOTECALL;
-                               }
-                               else
-                                       wake_req->fn_flag |= FLAGS_REMOTECALL;
-                       GSPRINTK(KERN_ALERT"%s: sending to origin remote callpfn cpu: 0x{%d} request->ticket{%d} \n",__func__,cpu,localticket_value);
-                       if ((cpu = find_kernel_for_pfn(pfn, &pfn_list_head)) != -1){
-                               spin_unlock(&value->_sp);
-                               
-                               res = pcn_kmsg_send(cpu, (struct pcn_kmsg_message*)  ((_data->ops==WAKE_OPS)? (wake_req):(wait_req)));
-                       }
-               } else if (vma != NULL && !(vma->vm_flags & VM_PFNMAP) ) {
-                       if(_data->ops==WAIT_OPS){
-                                       wait_req->fn_flags |= FLAGS_ORIGINCALL;
-                               }
-                               else{
-                                       wake_req->fn_flag |= FLAGS_ORIGINCALL;
-                                       wake_req->rflag = current->pid;
-                               }
-                       GSPRINTK(KERN_ALERT"%s: sending to origin origin call cpu: 0x{%d} request->ticket{%d} \n",__func__,cpu,localticket_value);
-                       if ((cpu = find_kernel_for_pfn(pfn, &pfn_list_head)) != -1){
-                               spin_unlock(&value->_sp);
-                               
-                               res = pcn_kmsg_send(cpu, (struct pcn_kmsg_message*) ((_data->ops==WAKE_OPS)? (wake_req):(wait_req)));
-                       }
-               }
-
-       //      printk(KERN_ALERT"%s:goto sleep after ticket request: 0x{%d} {%d}\n",__func__,cpu,current->pid);
-               wait_event_interruptible(rq_ptr->_wq, (rq_ptr->status == DONE));
-               GSPRINTK(KERN_ALERT"%s:after wake up process: task woken{%d}\n",__func__,current->pid);
-
-out:
-   kfree(wake_req);
-   kfree(wait_req);
-   return 0;
-
-}
-
-
-int global_spinunlock(unsigned long uaddr, unsigned int fn_flag){
-
-       int localticket_value;
-       int res = 0;    int cpu=0;
-
-       _spin_key sk ;
-       spin_key_init(&sk);
-
-       getKey(uaddr, &sk,current->tgroup_home_id);
-       _spin_value *value = hashspinkey(&sk);
-
-
+               if(_data->ops==WAIT_OPS){
+                       wait_req->fn_flags |= FLAGS_REMOTECALL;
+               }
+               else{
+                       wake_req->fn_flag |= FLAGS_REMOTECALL;
+               //printk(KERN_ALERT"%s: uaddr{%lx}  uaddr2{%lx}\n",__func__,wake_req->uaddr,wake_req->uaddr2);
+               //printk(KERN_ALERT"%s: msg wake: uaddr {%lx}  uaddr2{%lx} ticket {%d} tghid{%d} bitset {%u} rflag{%d} pid{%d} ifn_flags{%lx} ops{%d} size{%d} \n", __func__,wake_req->uaddr,(wake_req->uaddr2),wake_req->ticket,wake_req->tghid,wake_req->bitset,wake_req->rflag,wake_req->pid,wake_req->fn_flag,_data->ops,sizeof(_remote_wakeup_request_t));
+               }
+               GSPRINTK(KERN_ALERT"%s: sending to origin remote callpfn cpu: 0x{%d} request->ticket{%d} \n",__func__,cpu,localticket_value);
+               if ((cpu = find_kernel_for_pfn(pfn, &pfn_list_head)) != -1){
+                       spin_unlock(&value->_sp);
 
+                       res = pcn_kmsg_send(cpu, (struct pcn_kmsg_message*)  ((_data->ops==WAKE_OPS)? (wake_req):(wait_req)));
+               }
+       } else if (vma != NULL && !(vma->vm_flags & VM_PFNMAP) ) {
+               if(_data->ops==WAIT_OPS){
+                       wait_req->fn_flags |= FLAGS_ORIGINCALL;
+               }
+               else{
+                       wake_req->fn_flag |= FLAGS_ORIGINCALL;
+                       wake_req->rflag = current->pid;
+               //printk(KERN_ALERT"%s: uaddr{%lx}  uaddr2{%lx}\n",__func__,wake_req->uaddr,wake_req->uaddr2);
+               //printk(KERN_ALERT"%s: msg wake: uaddr {%lx}  uaddr2{%lx} ticket {%d} tghid{%d} bitset {%u} rflag{%d} pid{%d} ifn_flags{%lx} ops{%d} size{%d} \n", __func__,wake_req->uaddr,(wake_req->uaddr2),wake_req->ticket,wake_req->tghid,wake_req->bitset,wake_req->rflag,wake_req->pid,wake_req->fn_flag,_data->ops,sizeof(_remote_wakeup_request_t));
+               }
+               GSPRINTK(KERN_ALERT"%s: sending to origin origin call cpu: 0x{%d} request->ticket{%d} \n",__func__,cpu,localticket_value);
+               if ((cpu = find_kernel_for_pfn(pfn, &pfn_list_head)) != -1){
+                       spin_unlock(&value->_sp);
 
-       _remote_key_request_t *request = kmalloc(sizeof(_remote_key_request_t),
-                                       GFP_ATOMIC);
-               printk(KERN_ALERT"%s: request -- entered whos calling{%s} \n", __func__,current->comm);
-               printk(KERN_ALERT"%s:  uaddr {%lx} fn_flag {%lx} val{%d}  pid{%d} \n",
-                                       __func__,uaddr,fn_flag,current->pid);
+                       res = pcn_kmsg_send(cpu, (struct pcn_kmsg_message*) ((_data->ops==WAKE_OPS)? (wake_req):(wait_req)));
+               }
+       }
 
-               // Finish constructing response
-               request->header.type = PCN_KMSG_TYPE_REMOTE_IPC_FUTEX_KEY_REQUEST;
-               request->header.prio = PCN_KMSG_PRIO_NORMAL;
-
-               struct vm_area_struct *vma;
-               vma = getVMAfromUaddr(uaddr);
-
-               request->flags = 0;
-               request->uaddr =(unsigned long)uaddr;
-               request->pid = current->pid;
-               //request->origin_pid = current->origin_pid;
-               request->tghid = current->tgroup_home_id;
-               request->fn_flags = fn_flag;
-
-               request->ticket = 2;// WAIT_RELEASE_TOKEN; //set the request to release lock
-
-               unsigned long pfn;
-               pte_t pte;
-               pte = *((pte_t *) do_page_walk((unsigned long)uaddr));
-       //      printk(KERN_ALERT"%s pte ptr : ox{%lx} cpu{%d} \n",__func__,pte,smp_processor_id());
-               pfn = pte_pfn(pte);
-               printk(KERN_ALERT"%s pte pfn : 0x{%lx}\n",__func__,pfn);
-
-
-
-           if(1){
-               //pcn_kmsg and wait
-               if (vma->vm_flags & VM_PFNMAP) {
-                               if ((cpu = find_kernel_for_pfn(pfn, &pfn_list_head)) != -1)
-                                               {
-         //                            printk(KERN_ALERT"%s: sending to origin pfn cpu: 0x{%d} request->ticket{%d} \n",__func__,cpu,request->ticket);
-                                       res = pcn_kmsg_send(cpu, (struct pcn_kmsg_message*) (request));
-                               }
-                       } else {//if ((fn_flag & FLAGS_ORIGINCALL)) {
-                               if ((cpu = find_kernel_for_pfn(pfn, &pfn_list_head)) != -1)
-                                               {
-           //                          printk(KERN_ALERT"%s: sending to origin pfn cpu: 0x{%d} request->ticket{%d} \n",__func__,cpu,request->ticket);
-                                       res = pcn_kmsg_send(cpu, (struct pcn_kmsg_message*) (request));
-                               }
-                       }
-               //check if it has acquired valid ticket
-               if((value->_st == HAS_TICKET) && !(value->lock_st)){
-           //          printk(KERN_ALERT"%s: rel lock in remote \n",__func__);
-                       cmpxchg(&value->_st, HAS_TICKET, INITIAL_STATE);// release lock in remote node
-               }
-           }
+       wait_event_interruptible(rq_ptr->_wq, (rq_ptr->status == DONE));
+       GSPRINTK(KERN_ALERT"%s:after wake up process: task woken{%d}\n",__func__,current->pid);
 
 out:
-       kfree(request);
+       kfree(wake_req);
+       kfree(wait_req);
        return 0;
+
 }
+
 static int __init global_spinlock_init(void)
 {
        int i=0;
@@ -370,18 +354,19 @@ static int __init global_spinlock_init(void)
                spin_lock_init(&spin_bucket[i]._sp);
                spin_bucket[i]._st = 0;//TBR
                spin_bucket[i]._ticket = 0;
-               spin_bucket[i].lock_st = 0;//TBR
+               spin_bucket[i].mig_st = NULL;
 
                INIT_LIST_HEAD(&spin_bucket[i]._lrq_head);
        }
 
        for (i = 0; i < ARRAY_SIZE(global_bucket); i++) {
-                       raw_spin_lock_init(&global_bucket[i].lock);
-                       global_bucket[i].thread_group_leader = NULL;
-                       global_bucket[i].worker_task=NULL;
-                       global_bucket[i].global_wq = NULL;
-                       global_bucket[i].free = 0;
-               }
+               spin_lock_init(&global_bucket[i].lock);
+               INIT_LIST_HEAD(&global_bucket[i].link);
+//             global_bucket[i].thread_group_leader = NULL;
+//             global_bucket[i].worker_task=NULL;
+//             global_bucket[i].global_wq = NULL;
+//             global_bucket[i].free = 0;
+       }
 
 
        return 0;
index de14c7b..871c292 100644 (file)
@@ -68,9 +68,9 @@ early_param("kernel_init", popcorn_kernel_init);
 
 
 typedef enum allVendors {
-           AuthenticAMD,
-           GenuineIntel,
-           unknown
+       AuthenticAMD,
+       GenuineIntel,
+       unknown
 } vendor;
 
 
@@ -124,54 +124,54 @@ void add_pfn_node(int kernel_number, unsigned long start_pfn_addr,unsigned long
        _pfn_range_list_t *Ptr = (_pfn_range_list_t *)kmalloc(sizeof(struct _pfn_range_list),GFP_KERNEL);
 
 
-    Ptr->start_pfn_addr = start_pfn_addr;
-    Ptr->end_pfn_addr = end_pfn_addr;
-    Ptr->kernel_number = kernel_number;
-    INIT_LIST_HEAD(&Ptr->pfn_list_member);
-    list_add(&Ptr->pfn_list_member, head);
+       Ptr->start_pfn_addr = start_pfn_addr;
+       Ptr->end_pfn_addr = end_pfn_addr;
+       Ptr->kernel_number = kernel_number;
+       INIT_LIST_HEAD(&Ptr->pfn_list_member);
+       list_add(&Ptr->pfn_list_member, head);
 }
 
 
 
 int delete_pfn(int kernel_number, struct list_head *head)
 {
-    struct list_head *iter;
-    _pfn_range_list_t *objPtr;
-
-    list_for_each(iter, head) {
-        objPtr = list_entry(iter, _pfn_range_list_t, pfn_list_member);
-        if(objPtr->kernel_number == kernel_number) {
-            list_del(&objPtr->pfn_list_member);
-            kfree(objPtr);
-            return 1;
-        }
-    }
+       struct list_head *iter;
+       _pfn_range_list_t *objPtr;
+
+       list_for_each(iter, head) {
+               objPtr = list_entry(iter, _pfn_range_list_t, pfn_list_member);
+               if(objPtr->kernel_number == kernel_number) {
+                       list_del(&objPtr->pfn_list_member);
+                       kfree(objPtr);
+                       return 1;
+               }
+       }
 }
 
 
 _pfn_range_list_t* find_pfn(int kernel_number,struct list_head *head)
 {
-    struct list_head *iter;
-    _pfn_range_list_t *objPtr;
-
-    list_for_each(iter, head) {
-        objPtr = list_entry(iter, _pfn_range_list_t, pfn_list_member);
-        if(objPtr->kernel_number == kernel_number) {
-                    return objPtr;
-                }
-    }
-    return NULL;
+       struct list_head *iter;
+       _pfn_range_list_t *objPtr;
+
+       list_for_each(iter, head) {
+               objPtr = list_entry(iter, _pfn_range_list_t, pfn_list_member);
+               if(objPtr->kernel_number == kernel_number) {
+                       return objPtr;
+               }
+       }
+       return NULL;
 }
 
 _pfn_range_list_t* d_pfn(struct list_head *head)
 {
-    struct list_head *iter;
-    _pfn_range_list_t *objPtr;
+       struct list_head *iter;
+       _pfn_range_list_t *objPtr;
 
-    list_for_each(iter, head) {
-        objPtr = list_entry(iter, _pfn_range_list_t, pfn_list_member);
-        printk("k {%d} s {%lx} e {%lx}",objPtr->kernel_number,objPtr->start_pfn_addr,objPtr->end_pfn_addr);
-    }
+       list_for_each(iter, head) {
+               objPtr = list_entry(iter, _pfn_range_list_t, pfn_list_member);
+               printk("k {%d} s {%lx} e {%lx}",objPtr->kernel_number,objPtr->start_pfn_addr,objPtr->end_pfn_addr);
+       }
 }
 
 
@@ -197,10 +197,10 @@ static int handle_remote_pfn_request(struct pcn_kmsg_message* inc_msg) {
        printk("%s : %d!!!", "handle_remote_pfn_request",_cpu);
 
        int i;
-                printk("\n");
-    _remote_pfn_request_t* msg = (_remote_pfn_request_t*) inc_msg;
-    _remote_pfn_response_t response;
-    _pfn_range_list_t data;
+       printk("\n");
+       _remote_pfn_request_t* msg = (_remote_pfn_request_t*) inc_msg;
+       _remote_pfn_response_t response;
+       _pfn_range_list_t data;
 
        printk("%s: Entered remote  pfn request \n", "handle_remote_pfn_request");
 
@@ -237,14 +237,14 @@ int send_pfn_request(int KernelId) {
        request->header.type = PCN_KMSG_TYPE_REMOTE_PFN_REQUEST;
        request->header.prio = PCN_KMSG_PRIO_NORMAL;
        _pfn_range_list_t *t = find_pfn(Kernel_Id,&pfn_list_head);
-    if(t!=NULL){
-       request->_data.kernel_number = t->kernel_number;
-       request->_data.start_pfn_addr = t->start_pfn_addr;
-       request->_data.end_pfn_addr = t->end_pfn_addr;
-       // Send response
-       res = pcn_kmsg_send_long(KernelId, (struct pcn_kmsg_message*) (request),
-                       sizeof(_remote_pfn_request_t) - sizeof(struct pcn_kmsg_hdr));
-    }
+       if(t!=NULL){
+               request->_data.kernel_number = t->kernel_number;
+               request->_data.start_pfn_addr = t->start_pfn_addr;
+               request->_data.end_pfn_addr = t->end_pfn_addr;
+               // Send response
+               res = pcn_kmsg_send_long(KernelId, (struct pcn_kmsg_message*) (request),
+                               sizeof(_remote_pfn_request_t) - sizeof(struct pcn_kmsg_hdr));
+       }
        return res;
 }
 
@@ -252,29 +252,29 @@ int _init_remote_pfn(void)
 {
        int i = 0;
 
-                       int result = 0;
-                       int retval;
+       int result = 0;
+       int retval;
 
-                       for (i = 0; i < NR_CPUS; i++) {
+       for (i = 0; i < NR_CPUS; i++) {
 
-                               flush_pfn_var();
-                               // Skip the current cpu
-                               if (i == _cpu)
-                                       continue;
-                               result = send_pfn_request(i);
+               flush_pfn_var();
+               // Skip the current cpu
+               if (i == _cpu)
+                       continue;
+               result = send_pfn_request(i);
 
-                               if (!result) {
+               if (!result) {
 
-                                       PRINTK("%s : go to sleep!!!!", __func__);
-                                                               wait_event_interruptible(wq_pfn, wait_pfn_list != -1);
-                                                               wait_pfn_list = -1;
+                       PRINTK("%s : go to sleep!!!!", __func__);
+                       wait_event_interruptible(wq_pfn, wait_pfn_list != -1);
+                       wait_pfn_list = -1;
 
-                                                               add_pfn_node(pfn_result->_data.kernel_number,pfn_result->_data.start_pfn_addr,pfn_result->_data.end_pfn_addr,&pfn_list_head);
+                       add_pfn_node(pfn_result->_data.kernel_number,pfn_result->_data.start_pfn_addr,pfn_result->_data.end_pfn_addr,&pfn_list_head);
 
-                               }
-                       }
+               }
+       }
 
-                       return 0;
+       return 0;
 }
 
 /*
@@ -287,23 +287,23 @@ int _init_local_pfn(void)
        unsigned int i;
        printk("%s : %d!!!", "_init_local_pfn: ",_cpu);
 
-         printk("POP_INIT:Kernel id is %d\n",Kernel_Id);
-         printk("POP_INIT: kernel start add is 0x%lx",kernel_start_addr);
-         printk("POP_INIT:max_low_pfn id is 0x%lx\n",PFN_PHYS(max_low_pfn));
+       printk("POP_INIT:Kernel id is %d\n",Kernel_Id);
+       printk("POP_INIT: kernel start add is 0x%lx",kernel_start_addr);
+       printk("POP_INIT:max_low_pfn id is 0x%lx\n",PFN_PHYS(max_low_pfn));
 
 
-         add_pfn_node(Kernel_Id,kernel_start_addr,PFN_PHYS(max_low_pfn),&pfn_list_head);
+       add_pfn_node(Kernel_Id,kernel_start_addr,PFN_PHYS(max_low_pfn),&pfn_list_head);
 
        return 0;
 }
 
 int _init_RemotePFN(void)
 {
-        _init_local_pfn();
-        _init_remote_pfn();
+       _init_local_pfn();
+       _init_remote_pfn();
 
-         d_pfn(&pfn_list_head);
-         return 0;
+       d_pfn(&pfn_list_head);
+       return 0;
 }
 
 void popcorn_init(void)
@@ -311,42 +311,42 @@ void popcorn_init(void)
 
        if(bucket_phys_addr != 0)
        {
-       int i=0;
-       ssize_t bucket_size =sizeof(long)*max_nodes;
+               int i=0;
+               ssize_t bucket_size =sizeof(long)*max_nodes;
 
 
-       printk("%s: POP_INIT:kernel bucket_phys_addr: 0x%lx\n","popcorn_init",
-                         (unsigned long) bucket_phys_addr);
-       printk("%s:POP_INIT:Called popcorn_init boot id--max_nodes :%d! %d\n","popcorn_init",max_nodes);
+               printk("%s: POP_INIT:kernel bucket_phys_addr: 0x%lx\n","popcorn_init",
+                               (unsigned long) bucket_phys_addr);
+               printk("%s:POP_INIT:Called popcorn_init boot id--max_nodes :%d! %d\n","popcorn_init",max_nodes);
 
-       token_bucket=ioremap_cache((resource_size_t)((void *) bucket_phys_addr),PAGE_SIZE);
+               token_bucket=ioremap_cache((resource_size_t)((void *) bucket_phys_addr),PAGE_SIZE);
 
-       if (!token_bucket) {
-                               printk("Failed to kmalloc token_bucket !\n");
-                               unsigned long pfn = (long) bucket_phys_addr >> PAGE_SHIFT;
-                               struct page *shared_page;
-                               shared_page = pfn_to_page(pfn);
-                               token_bucket = page_address(shared_page);
-                               void * kmap_addr = kmap(shared_page);
-                       }
+               if (!token_bucket) {
+                       printk("Failed to kmalloc token_bucket !\n");
+                       unsigned long pfn = (long) bucket_phys_addr >> PAGE_SHIFT;
+                       struct page *shared_page;
+                       shared_page = pfn_to_page(pfn);
+                       token_bucket = page_address(shared_page);
+                       void * kmap_addr = kmap(shared_page);
+               }
 
-       PRINTK("%s: POP_INIT:token_bucket addr: 0x%p\n",__func__, token_bucket);
-                       for(i=0;i<max_nodes;i++)
-                       {
-                               if(token_bucket[i]==0)
-                               {   token_bucket[i]=1;
-                                       Kernel_Id=i+1;break;
-                               }
+               PRINTK("%s: POP_INIT:token_bucket addr: 0x%p\n",__func__, token_bucket);
+               for(i=0;i<max_nodes;i++)
+               {
+                       if(token_bucket[i]==0)
+                       {   token_bucket[i]=1;
+                               Kernel_Id=i+1;break;
                        }
+               }
 
-       PRINTK("%s: POP_INIT:token_bucket Initial values; \n",__func__);
-       for(i=0;i<max_nodes;i++)
+               PRINTK("%s: POP_INIT:token_bucket Initial values; \n",__func__);
+               for(i=0;i<max_nodes;i++)
                {
-               printk("%d\t",token_bucket[i]);
+                       printk("%d\t",token_bucket[i]);
                }
 
 
-       printk("POP_INIT:Virt add : 0x%p --- shm kernel id address: 0x%lx\n",token_bucket,bucket_phys_addr);
+               printk("POP_INIT:Virt add : 0x%p --- shm kernel id address: 0x%lx\n",token_bucket,bucket_phys_addr);
        }
 
 
@@ -354,7 +354,7 @@ void popcorn_init(void)
        int vendor_id=0;
        printk("POP_INIT:first_online_node{%d} cpumask_first{%d} \n",first_online_node,cpumask_first(cpu_present_mask));
        struct cpuinfo_x86 *c = &boot_cpu_data;
-       
+
 
        if(!strcmp(((const char *) c->x86_vendor_id),((const char *)"AuthenticAMD"))){
                vendor amd = AuthenticAMD;
@@ -365,14 +365,14 @@ void popcorn_init(void)
                vendor_id = intel;
        }
        printk("POP_INIT:vendor{%s} cpufam{%d} model{%u} cpucnt{%d} jhas{%u}\n",c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown",c->x86,c->x86_model,vendor_id, (jhash_2words((u32)vendor_id,cpumask_first(cpu_present_mask), JHASH_INITVAL) & ((1<<8)-1)));
-       
-       
+
+
        Kernel_Id=cpumask_first(cpu_present_mask);
 
-    printk("POP_INIT:Kernel id is %d\n",Kernel_Id);
-    printk("POP_INIT: kernel start add is 0x%lx",kernel_start_addr);
-    printk("POP_INIT:max_low_pfn id is 0x%lx\n",PFN_PHYS(max_low_pfn));
-    printk("POP_INIT:min_low_pfn id is 0x%lx\n",PFN_PHYS(min_low_pfn));
+       printk("POP_INIT:Kernel id is %d\n",Kernel_Id);
+       printk("POP_INIT: kernel start add is 0x%lx",kernel_start_addr);
+       printk("POP_INIT:max_low_pfn id is 0x%lx\n",PFN_PHYS(max_low_pfn));
+       printk("POP_INIT:min_low_pfn id is 0x%lx\n",PFN_PHYS(min_low_pfn));
 
 }
 
@@ -382,57 +382,57 @@ void popcorn_init(void)
  * ****************************** Message structures for obtaining PID status ********************************
  */
 
- void add_node(_remote_cpu_info_data_t *arg, struct list_head *head)
- {
-   _remote_cpu_info_list_t *Ptr =
-         (_remote_cpu_info_list_t *)kmalloc(sizeof(_remote_cpu_info_list_t), GFP_KERNEL);
-   if (!Ptr) {
-     printk(KERN_ALERT"%s: can not allocate memory for kernel node descriptor\n", __func__);
-    return;
-   }
-   printk("%s: _remote_cpu_info_list_t %ld, _remote_cpu_info_data_t %ld\n",
-         __func__, sizeof(_remote_cpu_info_list_t), sizeof(_remote_cpu_info_data_t) );
-
-   INIT_LIST_HEAD(&(Ptr->cpu_list_member));
-  memcpy(&(Ptr->_data), arg, sizeof(_remote_cpu_info_data_t)); //Ptr->_data = *arg;
-   list_add(&Ptr->cpu_list_member, head);
- }
-
- int find_and_delete(int cpuno, struct list_head *head)
- {
-     struct list_head *iter;
-     _remote_cpu_info_list_t *objPtr;
-
-     list_for_each(iter, head) {
-         objPtr = list_entry(iter, _remote_cpu_info_list_t, cpu_list_member);
-         if(objPtr->_data._processor == cpuno) {
-             list_del(&objPtr->cpu_list_member);
-             kfree(objPtr);
-             return 1;
-         }
-     }
-     return 0;
- }
-
- #define DISPLAY_BUFFER 128
- static void display(struct list_head *head)
- {
-     struct list_head *iter;
-     _remote_cpu_info_list_t *objPtr;
-     char buffer[DISPLAY_BUFFER];
-
-     list_for_each(iter, head) {
-         objPtr = list_entry(iter, _remote_cpu_info_list_t, cpu_list_member);
-
-         memset(buffer, 0, DISPLAY_BUFFER);
-         cpumask_scnprintf(buffer, (DISPLAY_BUFFER -1), &(objPtr->_data._cpumask));
-         printk("%s: cpu:%d fam:%d %s\n", __func__,
-                 objPtr->_data._processor, objPtr->_data._cpu_family,
-                 buffer);
-     }
- }
-
- ///////////////////////////////////////////////////////////////////////////////
+void add_node(_remote_cpu_info_data_t *arg, struct list_head *head)
+{
+       _remote_cpu_info_list_t *Ptr =
+               (_remote_cpu_info_list_t *)kmalloc(sizeof(_remote_cpu_info_list_t), GFP_KERNEL);
+       if (!Ptr) {
+               printk(KERN_ALERT"%s: can not allocate memory for kernel node descriptor\n", __func__);
+               return;
+       }
+       printk("%s: _remote_cpu_info_list_t %ld, _remote_cpu_info_data_t %ld\n",
+                       __func__, sizeof(_remote_cpu_info_list_t), sizeof(_remote_cpu_info_data_t) );
+
+       INIT_LIST_HEAD(&(Ptr->cpu_list_member));
+       memcpy(&(Ptr->_data), arg, sizeof(_remote_cpu_info_data_t)); //Ptr->_data = *arg;
+       list_add(&Ptr->cpu_list_member, head);
+}
+
+int find_and_delete(int cpuno, struct list_head *head)
+{
+       struct list_head *iter;
+       _remote_cpu_info_list_t *objPtr;
+
+       list_for_each(iter, head) {
+               objPtr = list_entry(iter, _remote_cpu_info_list_t, cpu_list_member);
+               if(objPtr->_data._processor == cpuno) {
+                       list_del(&objPtr->cpu_list_member);
+                       kfree(objPtr);
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+#define DISPLAY_BUFFER 128
+static void display(struct list_head *head)
+{
+       struct list_head *iter;
+       _remote_cpu_info_list_t *objPtr;
+       char buffer[DISPLAY_BUFFER];
+
+       list_for_each(iter, head) {
+               objPtr = list_entry(iter, _remote_cpu_info_list_t, cpu_list_member);
+
+               memset(buffer, 0, DISPLAY_BUFFER);
+               cpumask_scnprintf(buffer, (DISPLAY_BUFFER -1), &(objPtr->_data._cpumask));
+               printk("%s: cpu:%d fam:%d %s\n", __func__,
+                               objPtr->_data._processor, objPtr->_data._cpu_family,
+                               buffer);
+       }
+}
+
+///////////////////////////////////////////////////////////////////////////////
 struct _remote_cpu_info_request {
        struct pcn_kmsg_hdr header;
        _remote_cpu_info_data_t _data;
@@ -529,7 +529,7 @@ int fill_cpu_info(_remote_cpu_info_data_t *res) {
 
 #ifdef CONFIG_X86_64
        if (c->x86_tlbsize > 0)
-       res->_TLB_size= c->x86_tlbsize;
+               res->_TLB_size= c->x86_tlbsize;
 #endif
        res->_clflush_size = c->x86_clflush_size;
        res->_cache_alignment = c->x86_cache_alignment;
@@ -591,10 +591,10 @@ static int handle_remote_proc_cpu_info_request(struct pcn_kmsg_message* inc_msg)
 
        printk("%s : global cpus online in kernel %d!!!", "handle_remote_proc_cpu_info_request",_cpu);
 
-                       for_each_global_online_cpu(i) {
-                               printk("%d %t", i);
-                                }
-                       printk("\n");
+       for_each_global_online_cpu(i) {
+               printk("%d %t", i);
+       }
+       printk("\n");
 
        // Send response
        pcn_kmsg_send_long(msg->header.from_cpu,
@@ -608,28 +608,28 @@ static int handle_remote_proc_cpu_info_request(struct pcn_kmsg_message* inc_msg)
 
 int send_cpu_info_request(int KernelId) {
 
-        int res = 0;
-        _remote_cpu_info_request_t* request = kmalloc(
-                          sizeof(_remote_cpu_info_request_t),
-                                GFP_KERNEL);
-        // Build request
-        request->header.type = PCN_KMSG_TYPE_REMOTE_PROC_CPUINFO_REQUEST;
-        request->header.prio = PCN_KMSG_PRIO_NORMAL;
-        //      request->_data._cpumask = kmalloc( sizeof(struct cpumask), GFP_KERNEL);
+       int res = 0;
+       _remote_cpu_info_request_t* request = kmalloc(
+                       sizeof(_remote_cpu_info_request_t),
+                       GFP_KERNEL);
+       // Build request
+       request->header.type = PCN_KMSG_TYPE_REMOTE_PROC_CPUINFO_REQUEST;
+       request->header.prio = PCN_KMSG_PRIO_NORMAL;
+       //      request->_data._cpumask = kmalloc( sizeof(struct cpumask), GFP_KERNEL);
 
-        fill_cpu_info(&request->_data);
+       fill_cpu_info(&request->_data);
 
-        memcpy(&(request->_data._cpumask), cpu_present_mask, sizeof(cpu_present_mask));
-        request->_data._processor = my_cpu;
+       memcpy(&(request->_data._cpumask), cpu_present_mask, sizeof(cpu_present_mask));
+       request->_data._processor = my_cpu;
 
 
-         // Send response
-         res = pcn_kmsg_send_long(KernelId, (struct pcn_kmsg_message*) (request),
-                                sizeof(_remote_cpu_info_request_t) - sizeof(struct pcn_kmsg_hdr));
+       // Send response
+       res = pcn_kmsg_send_long(KernelId, (struct pcn_kmsg_message*) (request),
+                       sizeof(_remote_cpu_info_request_t) - sizeof(struct pcn_kmsg_hdr));
 
-         //kfree(request);
+       //kfree(request);
 
-         return res;
+       return res;
 }
 
 /*
@@ -648,31 +648,31 @@ int _init_RemoteCPUMask(void)
        int result = 0;
        int retval;
 
-         for (i = 0; i < NR_CPUS; i++) {
-                 flush_cpu_info_var();
-
-            // Skip the current cpu
-            //if (i == _cpu)
-            if (cpumask_test_cpu(i, cpu_present_mask)) {
-        printk("%s: cpu already known %i continue.\n", __func__,  i);
-              continue;
-        }
-            printk("%s: checking cpu %d.\n", __func__, i);
-            result = send_cpu_info_request(i);
-            if (!result) {
-              PRINTK("%s : go to sleep!!!!", __func__);
-              wait_event_interruptible(wq_cpu, wait_cpu_list != -1);
-              wait_cpu_list = -1;
-
-        // TODO
-        //      cpumask_or(cpu_global_online_mask,cpu_global_online_mask,(const struct cpumask *)(cpu_result->_data._cpumask));
+       for (i = 0; i < NR_CPUS; i++) {
+               flush_cpu_info_var();
 
-              add_node(&cpu_result->_data,&rlist_head);
-              display(&rlist_head);
-            }
-          }
+               // Skip the current cpu
+               //if (i == _cpu)
+               if (cpumask_test_cpu(i, cpu_present_mask)) {
+                       printk("%s: cpu already known %i continue.\n", __func__,  i);
+                       continue;
+               }
+               printk("%s: checking cpu %d.\n", __func__, i);
+               result = send_cpu_info_request(i);
+               if (!result) {
+                       PRINTK("%s : go to sleep!!!!", __func__);
+                       wait_event_interruptible(wq_cpu, wait_cpu_list != -1);
+                       wait_cpu_list = -1;
+
+                       // TODO
+                       //      cpumask_or(cpu_global_online_mask,cpu_global_online_mask,(const struct cpumask *)(cpu_result->_data._cpumask));
+
+                       add_node(&cpu_result->_data,&rlist_head);
+                       display(&rlist_head);
+               }
+       }
 
-               printk("%s : global cpus online in kernel %d!!!", "_init_RemoteCPUMask",_cpu);
+       printk("%s : global cpus online in kernel %d!!!", "_init_RemoteCPUMask",_cpu);
 
        return 0;
 }
@@ -682,25 +682,25 @@ static int __init cpu_info_handler_init(void)
 {
 
 #ifndef SUPPORT_FOR_CLUSTERING
-   _cpu = smp_processor_id();
+       _cpu = smp_processor_id();
 #else
-   _cpu = my_cpu;
+       _cpu = my_cpu;
 #endif
 
-    INIT_LIST_HEAD(&rlist_head);
+       INIT_LIST_HEAD(&rlist_head);
 
-    INIT_LIST_HEAD(&pfn_list_head);
+       INIT_LIST_HEAD(&pfn_list_head);
 
 
        pcn_kmsg_register_callback(PCN_KMSG_TYPE_REMOTE_PROC_CPUINFO_REQUEST,
-                                               handle_remote_proc_cpu_info_request);
+                       handle_remote_proc_cpu_info_request);
        pcn_kmsg_register_callback(PCN_KMSG_TYPE_REMOTE_PROC_CPUINFO_RESPONSE,
-                                                       handle_remote_proc_cpu_info_response);
+                       handle_remote_proc_cpu_info_response);
 
        pcn_kmsg_register_callback(PCN_KMSG_TYPE_REMOTE_PFN_REQUEST,
-                                                       handle_remote_pfn_request);
-               pcn_kmsg_register_callback(PCN_KMSG_TYPE_REMOTE_PFN_RESPONSE,
-                                                               handle_remote_pfn_response);
+                       handle_remote_pfn_request);
+       pcn_kmsg_register_callback(PCN_KMSG_TYPE_REMOTE_PFN_RESPONSE,
+                       handle_remote_pfn_response);
 
 
        return 0;
index f9e7ff5..e566145 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/popcorn_cpuinfo.h>
 #include <linux/unistd.h>
 #include <linux/tsacct_kern.h>
-#include <linux/popcorn.h>
 #include <linux/syscalls.h>
 #include <linux/kernel.h>
 #include <linux/proc_fs.h>
@@ -57,8 +56,8 @@ unsigned long get_percpu_old_rsp(void);
 #include <linux/fcntl.h>
 #include "futex_remote.h"
 
-#define FPU_ 1
-//#undef FPU_
+//#define FPU_ 1
+#undef FPU_
 /**
  * General purpose configuration
  */
@@ -79,12 +78,13 @@ unsigned long get_percpu_old_rsp(void);
 
 // Whether or not to expose a proc entry that we can publish
 // information to.
-//#undef PROCESS_SERVER_HOST_PROC_ENTRY
-#define PROCESS_SERVER_HOST_PROC_ENTRY
+#undef PROCESS_SERVER_HOST_PROC_ENTRY
+//#define PROCESS_SERVER_HOST_PROC_ENTRY
 
 /**
  * Use the preprocessor to turn off printk.
  */
+#define POPCORN_MAX_PATH 512 
 #define PROCESS_SERVER_VERBOSE 0
 #if PROCESS_SERVER_VERBOSE
 #define PSPRINTK(...) printk(__VA_ARGS__)
@@ -282,7 +282,6 @@ typedef enum _lamport_barrier_state {
 /**
  * Library
  */
-#define POPCORN_MAX_PATH 512
 /**
  * Some piping for linking data entries
  * and identifying data entry types.
@@ -1141,6 +1140,7 @@ typedef struct {
    unsigned char task_fpu_counter;
    unsigned char thread_has_fpu;
    union thread_xstate fpu_state; // FPU migration support
+#endif
 } back_migration_work_t;
 
 /**
@@ -1288,6 +1288,7 @@ get_counter_phys_data_t* get_counter_phys_data = NULL;
 
 #ifdef PROCESS_SERVER_HOST_PROC_ENTRY
 struct proc_dir_entry *_proc_entry = NULL;
+struct proc_dir_entry *_lamport_proc_entry = NULL;
 static void proc_track_data(int entry, unsigned long long time);//proto
 static void proc_data_init();
 typedef struct _proc_data {
@@ -3297,6 +3298,44 @@ static void dump_lamport_queue(lamport_barrier_queue_t* queue) {
     }
 }
 
+static void dump_lamport_queue_alwaysprint(lamport_barrier_queue_t* queue) {
+     lamport_barrier_entry_t* curr = queue->queue;
+     int queue_pos = 0;
+     printk("Queue %p:\n",__func__,queue);
+     printk("  tgroup_home_cpu: %d\n",queue->tgroup_home_cpu);
+     printk("  tgroup_home_id: %d\n",queue->tgroup_home_id);
+     printk("  Addr: %lx\n",queue->address);
+     printk("  is_heavy: %d\n",queue->is_heavy);
+     printk("  active_timestamp: %llx\n",queue->active_timestamp);
+     printk("  Entries:\n");
+     while(curr) {
+         printk("    Entry, Queue position %d\n",queue_pos++);
+         printk("\t   timestamp: %llx\n",curr->timestamp);
+         printk("\t   is_heavy: %d\n",curr->is_heavy);
+         printk("\t   cpu: %d\n",curr->cpu);
+         curr = (lamport_barrier_entry_t*)curr->header.next;
+     }
+}
+
+static void dump_lamport_queue_alert(lamport_barrier_queue_t* queue) {
+     lamport_barrier_entry_t* curr = queue->queue;
+     int queue_pos = 0;
+     printk(KERN_ALERT"Queue %p:\n",__func__,queue);
+     printk(KERN_ALERT"  tgroup_home_cpu: %d\n",queue->tgroup_home_cpu);
+     printk(KERN_ALERT"  tgroup_home_id: %d\n",queue->tgroup_home_id);
+     printk(KERN_ALERT"  Addr: %lx\n",queue->address);
+     printk(KERN_ALERT"  is_heavy: %d\n",queue->is_heavy);
+     printk(KERN_ALERT"  active_timestamp: %llx\n",queue->active_timestamp);
+     printk(KERN_ALERT"  Entries:\n");
+     while(curr) {
+         printk(KERN_ALERT"    Entry, Queue position %d\n",queue_pos++);
+         printk(KERN_ALERT"\t   timestamp: %llx\n",curr->timestamp);
+         printk(KERN_ALERT"\t   is_heavy: %d\n",curr->is_heavy);
+         printk(KERN_ALERT"\t   cpu: %d\n",curr->cpu);
+         curr = (lamport_barrier_entry_t*)curr->header.next;
+     }
+}
+
 static void dump_all_lamport_queues() {
     lamport_barrier_queue_t* curr = _lamport_barrier_queue_head;
     while(curr) {
@@ -3305,6 +3344,22 @@ static void dump_all_lamport_queues() {
     }
 }
 
+static void dump_all_lamport_queues_alert() {
+     lamport_barrier_queue_t* curr = _lamport_barrier_queue_head;
+     while(curr) {
+         dump_lamport_queue_alert(curr);
+         curr = (lamport_barrier_queue_t*)curr->header.next;
+     }
+}
+
+static void dump_all_lamport_queues_alwaysprint() {
+     lamport_barrier_queue_t* curr = _lamport_barrier_queue_head;
+     while(curr) {
+        dump_lamport_queue_alwaysprint(curr);
+         curr = (lamport_barrier_queue_t*)curr->header.next;
+     }
+}
+
 /**
  * @brief Print information about the list.
  */
@@ -3622,14 +3677,8 @@ void process_mapping_request(struct work_struct* work) {
     };
     char *plpath = NULL, *lpath = NULL;
     int used_saved_mm = 0, found_vma = 1, found_pte = 1; 
-    char* plpath = NULL;
-    char lpath[512];
     int i;
     
-    // for perf
-    int used_saved_mm = 0;
-    int found_vma = 1;
-    int found_pte = 1;
 #ifdef PROCESS_SERVER_HOST_PROC_ENTRY
     unsigned long long mapping_response_send_time_start = 0;
     unsigned long long mapping_response_send_time_end = 0;
@@ -3742,21 +3791,11 @@ changed_can_be_cow:
              * if possible.
              */
             {
-            // Break all cows in this vma
-            if(can_be_cow) {
-                unsigned long cow_addr;
-                for(cow_addr = vma->vm_start; cow_addr < vma->vm_end; cow_addr += PAGE_SIZE) {
-                    break_cow(mm, vma, cow_addr);
-                }
-                // We no longer need a write lock after the break_cow process
-                // is complete, so downgrade the lock to a read lock.
-                downgrade_write(&mm->mmap_sem);
-            }
 
             // Now grab all the mappings that we can stuff into the response.
          if (0 != fill_physical_mapping_array(mm, vma, address,
                                                 &(response->mappings[0]),
-                                               MAX_MAPPINGS)) {
+                                               MAX_MAPPINGS,can_be_cow)) {
                 // If the fill process fails, clear out all
                 // results.  Otherwise, we might trick the
                 // receiving cpu into thinking the target
@@ -3769,6 +3808,10 @@ changed_can_be_cow:
                 }                    
             }
 
+            if(can_be_cow) {
+                downgrade_write(&mm->mmap_sem);
+            }
+
             }
 
             response->header.type = PCN_KMSG_TYPE_PROC_SRV_MAPPING_RESPONSE;
@@ -3782,7 +3825,7 @@ changed_can_be_cow:
             response->vaddr_size = vma->vm_end - vma->vm_start;
             response->prot = vma->vm_page_prot;
             response->vm_flags = vma->vm_flags;
-            if(vma->vm_file == NULL) {
+            if(vma->vm_file == NULL || !w->need_vma) {
                  response->path[0] = '\0';
             } else {    
                 plpath = d_path(&vma->vm_file->f_path,lpath,512);
@@ -3851,10 +3894,10 @@ changed_can_be_cow:
     }
 
     // Send response
-    if(response.present) {
+    if(response->present) {
 #ifdef PROCESS_SERVER_HOST_PROC_ENTRY
         mapping_response_send_time_start = native_read_tsc();
-        response.send_time = mapping_response_send_time_start;
+        response->send_time = mapping_response_send_time_start;
 #endif
         DO_UNTIL_SUCCESS(pcn_kmsg_send_long(w->from_cpu,
                             (struct pcn_kmsg_long_message*)(response),
@@ -4128,14 +4171,13 @@ done:
 
       if(mm_to_munmap) {
         PS_DOWN_WRITE(&mm_to_munmap->mmap_sem);
-        current->enable_distributed_munmap = 0;
         do_munmap(mm_to_munmap, w->vaddr_start, w->vaddr_size);
-        current->enable_distributed_munmap = 1;
         PS_UP_WRITE(&mm_to_munmap->mmap_sem);
         }
-       else
+       else{
        printk("%s: unexpected error task %p pid %d comm %s task->mm %p\n", 
                 __func__, task,task->pid,task->comm, (task ? task->mm : 0) );
+       }
     // munmap the specified region in any saved mm's as well.
     // This keeps old mappings saved in the mm of dead thread
     // group members from being resolved accidentally after
@@ -4159,17 +4201,15 @@ found:
 
     if (to_munmap && to_munmap->mm) {
         PS_DOWN_WRITE(&to_munmap->mm->mmap_sem);
-        current->enable_distributed_munmap = 0;
         do_munmap(to_munmap->mm, w->vaddr_start, w->vaddr_size);
-        current->enable_distributed_munmap = 1;
         if (to_munmap && to_munmap->mm)
             PS_UP_WRITE(&to_munmap->mm->mmap_sem);
-        else
+        else{
             printk(KERN_ALERT"%s: ERROR2: to_munmap %p mm %p\n", __func__, to_munmap, to_munmap?to_munmap->mm:0);
-    }
-    else if (to_munmap) // It is OK for to_munmap to be null, but not to_munmap->mm
+    }}
+    else if (to_munmap){ // It is OK for to_munmap to be null, but not to_munmap->mm
         printk(KERN_ALERT"%s: ERROR1: to_munmap %p mm %p\n", __func__, to_munmap, to_munmap?to_munmap->mm:0);
-
+       }
     // Construct response
     response.header.type = PCN_KMSG_TYPE_PROC_SRV_MUNMAP_RESPONSE;
     response.header.prio = PCN_KMSG_PRIO_NORMAL;
@@ -4255,12 +4295,9 @@ done:
     read_unlock(&tasklist_lock);
 
       if(mm_to_munmap) {
-        PS_DOWN_WRITE(&mm_to_munmap->mmap_sem);
-        current->enable_distributed_munmap = 0;
-        do_munmap(mm_to_munmap, start, len);
-        current->enable_distributed_munmap = 1;
-        PS_UP_WRITE(&mm_to_munmap->mmap_sem);
-        }
+        do_mprotect(task,mm_to_munmap,start,len,prot,0);
+        goto early_exit;
+       }
 
 
     // munmap the specified region in any saved mm's as well.
@@ -4285,14 +4322,10 @@ found:
     PS_SPIN_UNLOCK(&_saved_mm_head_lock);
 
     if(to_munmap != NULL) {
-        PS_DOWN_WRITE(&to_munmap->mm->mmap_sem);
-        current->enable_distributed_munmap = 0;
-        do_munmap(to_munmap->mm, start, len);
-        current->enable_distributed_munmap = 1;
-        PS_UP_WRITE(&to_munmap->mm->mmap_sem);
+      do_mprotect(NULL,to_munmap->mm,start,len,prot,0);
     }
 
-    
+early_exit:
     // Construct response
     response.header.type = PCN_KMSG_TYPE_PROC_SRV_MPROTECT_RESPONSE;
     response.header.prio = PCN_KMSG_PRIO_NORMAL;
@@ -4394,6 +4427,7 @@ search_exit:
 
     // Now, transplant the state into the shadow process
     memcpy(regs, &w->regs, sizeof(struct pt_regs));
+
     task->previous_cpus = w->previous_cpus;
     task->thread.fs = w->thread_fs;
     task->thread.gs = w->thread_gs;
@@ -4403,6 +4437,7 @@ search_exit:
     task->thread.fsindex = w->thread_fsindex;
     task->thread.gsindex = w->thread_gsindex;
 
+
 #ifdef FPU_   
       //FPU migration --- server (back migration)
           if (w->task_flags & PF_USED_MATH)
@@ -5835,7 +5870,7 @@ static int handle_clone_request(struct pcn_kmsg_message* inc_msg) {
 
     perf_cc = native_read_tsc();
 
-    PSPRINTK("%s: entered\n",__func__);
+    printk("%s: entered\n",__func__);
     
     /*
      * Remember this request
@@ -5899,7 +5934,7 @@ static int handle_clone_request(struct pcn_kmsg_message* inc_msg) {
     clone_data->remote_blocked = request->remote_blocked ;
     clone_data->remote_real_blocked = request->remote_real_blocked;
     clone_data->remote_saved_sigmask = request->remote_saved_sigmask ;
-    clone_data->remote_pending = request->remote_pending;
+    //clone_data->remote_pending = request->remote_pending;
 
     clone_data->sas_ss_sp = request->sas_ss_sp;
     clone_data->sas_ss_size = request->sas_ss_size;
@@ -5940,8 +5975,7 @@ static int handle_clone_request(struct pcn_kmsg_message* inc_msg) {
     }
 
     spin_unlock_irqrestore(&_data_head_lock,lockflags);
-
-    add_data_entry(clone_data);
+#endif
 
 perf_dd = native_read_tsc();
 
@@ -6241,7 +6275,7 @@ int process_server_import_address_space(unsigned long* ip,
 
     perf_a = native_read_tsc();
     
-    PSPRINTK("import address space\n");
+    printk("import address space\n");
     
     // Verify that we're a delegated task // deadlock.
 #ifdef PROCESS_SERVER_USE_KMOD
@@ -6340,7 +6374,6 @@ int process_server_import_address_space(unsigned long* ip,
             get_file(f);
             current->mm->exe_file = f;
             filp_close(f,NULL);
-        }
         } else {
             printk("%s: Error opening file %s\n",__func__,clone_data->exe_path);
         }
@@ -6378,7 +6411,7 @@ int process_server_import_address_space(unsigned long* ip,
         {
         struct vm_area_struct* vma_out = NULL;
         // fetch stack
-        process_server_try_handle_mm_fault(current->mm,
+        process_server_pull_remote_mappings(current->mm,
                                            NULL,
                                            clone_data->stack_start,
                                            NULL,
@@ -6619,11 +6652,11 @@ int process_server_import_address_space(unsigned long* ip,
     sigorsets(&current->blocked,&current->blocked,&clone_data->remote_blocked) ;
     sigorsets(&current->real_blocked,&current->real_blocked,&clone_data->remote_real_blocked);
     sigorsets(&current->saved_sigmask,&current->saved_sigmask,&clone_data->remote_saved_sigmask);
-    current->pending = clone_data->remote_pending;
+    ///current->pending = clone_data->remote_pending;
     current->sas_ss_sp = clone_data->sas_ss_sp;
     current->sas_ss_size = clone_data->sas_ss_size;
 
-    printk(KERN_ALERT "origin pid {%d}-{%d} \n",current->origin_pid,clone_data->origin_pid);
+    ///printk(KERN_ALERT "origin pid {%d}-{%d} \n",current->origin_pid,clone_data->origin_pid);
 
     int cnt=0;
      for(cnt=0;cnt<_NSIG;cnt++)
@@ -6657,8 +6690,6 @@ int process_server_import_address_space(unsigned long* ip,
     if ( !(clone_data->thread_fs) || !(__user_addr(clone_data->thread_fs)) ) {
       printk(KERN_ERR "%s: ERROR corrupted fs base address %p\n", __func__, clone_data->thread_fs);
     }    
-    current->thread.fsindex = clone_data->thread_fsindex;
-    current->thread.fs = clone_data->thread_fs;
     if (unlikely(fsindex | current->thread.fsindex))
       loadsegment(fs, current->thread.fsindex);
     else
@@ -6670,8 +6701,6 @@ int process_server_import_address_space(unsigned long* ip,
     if ( !(clone_data->thread_gs) && !(__user_addr(clone_data->thread_gs)) ) {
       printk(KERN_ERR "%s: ERROR corrupted gs base address %p\n", __func__, clone_data->thread_gs);      
     }
-    current->thread.gs = clone_data->thread_gs;    
-    current->thread.gsindex = clone_data->thread_gsindex;
     if (unlikely(gsindex | current->thread.gsindex))
       load_gs_index(current->thread.gsindex);
     else
@@ -6795,7 +6824,7 @@ long sys_process_server_import_task(void *info /*name*/,
     clone_data_t* clone_data = (clone_data_t*)info;
     unsigned long ip, sp;
     current->clone_data = clone_data;
-    printk("in sys_process_server_import_task pid{%d}, clone_data{%lx}\n",current->pid,(unsigned long)clone_data);
+    //printk("in sys_process_server_import_task pid{%d}, clone_data{%lx}\n",current->pid,(unsigned long)clone_data);
     process_server_import_address_space(&ip,&sp,regs);
     return 0;
 }
@@ -7525,17 +7554,6 @@ int process_server_pull_remote_mappings(struct mm_struct *mm,
     }
 #endif
     
-    if(vma) {
-        if(vma->vm_file) {
-            ppath = d_path(&vma->vm_file->f_path,
-                        path,512);
-        } else {
-            path[0] = '\0';
-        }
-
-        //PSPRINTK("working with provided vma: start{%lx}, end{%lx}, path{%s}\n",vma->vm_start,vma->vm_end,path);
-    }
-
     // The vma that's passed in might not always be correct.  find_vma fails by returning the wrong
     // vma when the vma is not present.  How ugly...
     if(vma && (vma->vm_start > address || vma->vm_end <= address)) {
@@ -7693,8 +7711,6 @@ int process_server_pull_remote_mappings(struct mm_struct *mm,
             if(data->path[0] == '\0') {       
                 PSPRINTK("mapping anonymous\n");
                 is_anonymous = 1;
-                current->enable_distributed_munmap = 0;
-                current->enable_do_mmap_pgoff_hook = 0;
                 // mmap parts that are missing, while leaving the existing
                 // parts untouched.
                 PS_DOWN_WRITE(&current->mm->mmap_sem);
@@ -7712,9 +7728,7 @@ int process_server_pull_remote_mappings(struct mm_struct *mm,
                if ( data->vm_flags & VM_NORESERVE )
                        printk(KERN_ALERT"MAPPING ANONYMOUS %p %p data: %lx vma: %lx {%lx-%lx} ret%lx\n",
                                __func__, data->mappings[i].vaddr, data->mappings[i].paddr, 
-                               data->vm_flags, vma?vma->vm_flags:0, vma?vma->vm_start:0, vma?vma->vm_end:0, err);
-*/                current->enable_distributed_munmap = 1;
-                current->enable_do_mmap_pgoff_hook = 1;
+                               data->vm_flags, vma?vma->vm_flags:0, vma?vma->vm_start:0, vma?vma->vm_end:0, err);*/
             } else {
                 //unsigned char used_existing;
                 PSPRINTK("opening file to map\n");
@@ -7743,8 +7757,6 @@ int process_server_pull_remote_mappings(struct mm_struct *mm,
                             data->vaddr_start, 
                             data->vaddr_size,
                             (unsigned long)f);
-                    current->enable_distributed_munmap = 0;
-                    current->enable_do_mmap_pgoff_hook = 0;
                     // mmap parts that are missing, while leaving the existing
                     // parts untouched.
                     PS_DOWN_WRITE(&current->mm->mmap_sem);
@@ -7801,14 +7813,6 @@ int process_server_pull_remote_mappings(struct mm_struct *mm,
             pte_provided = 1;
             unsigned long cow_addr;
 
-            // Break cow in this entire VMA
-            if(is_maybe_cow(vma)) {
-                PS_DOWN_WRITE(&current->mm->mmap_sem);
-                for(cow_addr = vma->vm_start; cow_addr < vma->vm_end; cow_addr += PAGE_SIZE) {
-                    break_cow(mm, vma, cow_addr);
-                }
-                PS_UP_WRITE(&current->mm->mmap_sem);
-            }
 
             for(i = 0; i < MAX_MAPPINGS; i++) {
                 if(data->mappings[i].present) {
@@ -7821,11 +7825,6 @@ int process_server_pull_remote_mappings(struct mm_struct *mm,
                                                        data->mappings[i].sz,
                                                        vm_get_page_prot(vma->vm_flags),
                                                        1);
-/*             if ( data->vm_flags & VM_NORESERVE )
-                       printk(KERN_ALERT"%s: NORESERVE %p %p data: %lx vma: %lx {%lx-%lx} ret%d\n",
-                               __func__,  data->mappings[i].vaddr, data->mappings[i].paddr,
-                               data->vm_flags, vma->vm_flags, vma->vm_start, vma->vm_end, tmp_err);
-*/
                     PS_UP_WRITE(&current->mm->mmap_sem);
                     if(tmp_err) remap_pfn_range_err = tmp_err;
                 }
@@ -7999,7 +7998,11 @@ int process_server_dup_task(struct task_struct* orig, struct task_struct* task)
     task->previous_cpus = 0;
     task->known_cpu_with_tgroup_mm = 0;
     task->return_disposition = RETURN_DISPOSITION_NONE;
-
+    task->surrogate = -1;
+    task->uaddr = 0;
+    task->futex_state = 0;
+    task->migration_state = 0;
+    spin_lock_init(&(task->mig_lock));
     // If this is pid 1 or 2, the parent cannot have been migrated
     // so it is safe to take on all local thread info.
     if(unlikely(orig->pid == 1 || orig->pid == 2)) {
@@ -8048,7 +8051,7 @@ int process_server_dup_task(struct task_struct* orig, struct task_struct* task)
  *
  * <MEASURE perf_process_server_do_migration>
  */
-static int do_migration_to_new_cpu(struct task_struct* task, int cpu) {
+int do_migration_to_new_cpu(struct task_struct* task, int cpu) {
     struct pt_regs *regs = task_pt_regs(task);
     // TODO: THIS IS WRONG, task flags is not what I want here.
     unsigned long clone_flags = task->clone_flags;
@@ -8062,7 +8065,7 @@ static int do_migration_to_new_cpu(struct task_struct* task, int cpu) {
     int lclone_request_id;
     int perf = -1;
 
-    PSPRINTK("process_server_do_migration\n");
+    printk("process_server_do_migration pid{%d} cpu {%d}\n",task->pid,cpu);
 
     // Nothing to do if we're migrating to the current cpu
     if(dst_cpu == _cpu) {
@@ -8076,29 +8079,19 @@ static int do_migration_to_new_cpu(struct task_struct* task, int cpu) {
     // Block its execution.
     __set_task_state(task,TASK_UNINTERRUPTIBLE);
 
-   // set_task_state(task,TASK_UNINTERRUPTIBLE); //mklinux_akshay modified to interruptible state
-
 
     int sig;
     struct task_struct *t=current;
     // Book keeping for previous cpu bitmask.
     set_bit(smp_processor_id(),&task->previous_cpus);
 
-    printk("Procee---Futex: blocked signals\n");
-    for (sig = 1; sig < NSIG; sig++) {
-       if (sigismember(&t->blocked, sig)) {
-               printk("POP: %d \n", sig);
-       }
-    }
-    printk("Procee---futex: pending signals\n");
-    for (sig = 1; sig < NSIG; sig++) {
-       if (sigismember(&t->pending.signal, sig)) {
-               printk("POP: %d \n", sig);
-       }
-    }
     // Book keeping for placeholder process.
+    spin_lock_irq(&(task->mig_lock));
     task->represents_remote = 1;
+    task->tgroup_distributed = 1;
     task->t_distributed = 1;
+    spin_unlock_irq(&(task->mig_lock));
+
 
     /*mklinux_akshay*/
     if(task->prev_pid==-1)
@@ -8110,7 +8103,6 @@ static int do_migration_to_new_cpu(struct task_struct* task, int cpu) {
 
 
     // Book keeping for distributed threads.
-    task->tgroup_distributed = 1;
 
     read_lock(&tasklist_lock);
     do_each_thread(g,tgroup_iterator) {
@@ -8222,7 +8214,7 @@ static int do_migration_to_new_cpu(struct task_struct* task, int cpu) {
     request->remote_blocked = task->blocked;
     request->remote_real_blocked = task->real_blocked;
     request->remote_saved_sigmask = task->saved_sigmask;
-    request->remote_pending = task->pending;
+   // request->remote_pending = task->pending;
     request->sas_ss_sp = task->sas_ss_sp;
     request->sas_ss_size = task->sas_ss_size;
     int cnt = 0;
@@ -8243,12 +8235,12 @@ static int do_migration_to_new_cpu(struct task_struct* task, int cpu) {
 
     request->thread_sp0 = task->thread.sp0;
     request->thread_sp = task->thread.sp;
-    //printk("%s: usersp percpu %lx thread %lx\n", __func__, percpu_read(old_rsp), task->thread.usersp);
+    //printk("%s: usersp percpu %lx thread %lx fs where it migrated {%lx}\n", __func__, get_percpu_old_rsp(), task->thread.usersp,task->thread.fs);
     // if (percpu_read(old_rsp), task->thread.usersp) set to 0 otherwise copy
     _usersp = get_percpu_old_rsp();
     if (task->thread.usersp != _usersp) {
-        printk("%s: USERSP %lx %lx\n",
-                __func__, task->thread.usersp, _usersp);
+       // printk("%s: USERSP %lx %lx\n",
+         //       __func__, task->thread.usersp, _usersp);
         request->thread_usersp = _usersp;
     } else {
         request->thread_usersp = task->thread.usersp;
@@ -8267,7 +8259,7 @@ static int do_migration_to_new_cpu(struct task_struct* task, int cpu) {
     request->thread_fsindex = task->thread.fsindex;
     savesegment(fs, fsindex);
     if (fsindex != request->thread_fsindex)
-        printk(KERN_ALERT"%s: fsindex %x (TLS_SEL:%x) thread %x\n", __func__, fsindex, FS_TLS_SEL, request->thread_fsindex);
+        //printk(KERN_ALERT"%s: fsindex %x (TLS_SEL:%x) thread %x\n", __func__, fsindex, FS_TLS_SEL, request->thread_fsindex);
     request->thread_fs = task->thread.fs;
     rdmsrl(MSR_FS_BASE, fs);
     if (fs != request->thread_fs) {
@@ -8327,10 +8319,13 @@ PSPRINTK(KERN_ERR"%s: task flags %x fpu_counter %x has_fpu %x [%d:%d] %d:%d %x\n
 
     kfree(request);
 
+    printk(KERN_ALERT"Migration done\n");
     //dump_task(task,regs,request->stack_ptr);
     
     PERF_MEASURE_STOP(&perf_process_server_do_migration,"migration to new cpu",perf);
 
+    
+    __set_task_state(task,TASK_UNINTERRUPTIBLE);
     return PROCESS_SERVER_CLONE_SUCCESS;
 
 }
@@ -8341,7 +8336,7 @@ PSPRINTK(KERN_ERR"%s: task flags %x fpu_counter %x has_fpu %x [%d:%d] %d:%d %x\n
  *
  * <MEASURE perf_process_server_do_migration>
  */
-static int do_migration_back_to_previous_cpu(struct task_struct* task, int cpu) {
+int do_migration_back_to_previous_cpu(struct task_struct* task, int cpu) {
     back_migration_t *mig =NULL;
     struct pt_regs* regs = task_pt_regs(task);
 
@@ -8380,7 +8375,7 @@ static int do_migration_back_to_previous_cpu(struct task_struct* task, int cpu)
     mig->thread_fs       = task->thread.fs;
     mig->thread_gs       = task->thread.gs;
 
-unsigned long _usersp = get_percpu_old_rsp();
+    _usersp = get_percpu_old_rsp();
 if (task->thread.usersp != _usersp) { 
   printk("%s: USERSP %lx %lx\n",
     __func__, task->thread.usersp, _usersp);
@@ -8388,11 +8383,14 @@ if (task->thread.usersp != _usersp) {
 }else
   mig->thread_usersp = task->thread.usersp;
 
+
     mig->thread_es       = task->thread.es;
     mig->thread_ds       = task->thread.ds;
     mig->thread_fsindex  = task->thread.fsindex;
     mig->thread_gsindex  = task->thread.gsindex;
-      //FPU support --- initiator (back migration?)
+
+    //FPU support --- initiator (back migration?)
+
 #ifdef FPU_   
   mig->task_flags      = task->flags;
        mig->task_fpu_counter = task->fpu_counter;
@@ -8422,6 +8420,7 @@ if (task->thread.usersp != _usersp) {
 
     pcn_kmsg_free_msg(mig);
     PERF_MEASURE_STOP(&perf_process_server_do_migration,"back migration",perf);
 
     return PROCESS_SERVER_CLONE_SUCCESS;
 }
@@ -8447,7 +8446,7 @@ int process_server_do_migration(struct task_struct* task, int cpu) {
     int ret = 0;
 
 #ifndef SUPPORT_FOR_CLUSTERING
-    printk(KERN_ALERT"%s: normal migration\n",__func__);
+    printk(KERN_ALERT"%s: normal migration {%d}\n",__func__,cpu);
     if(test_bit(cpu,&task->previous_cpus)) {
         ret = do_migration_back_to_previous_cpu(task,cpu);
     } else {
@@ -8459,7 +8458,7 @@ int process_server_do_migration(struct task_struct* task, int cpu) {
                       "(cpu: %d present_mask)\n", __func__, task, cpu);
         return -EBUSY;
     }
-    printk(KERN_ALERT"%s: clustering activated\n",__func__);
+    //printk(KERN_ALERT"%s: clustering activated\n",__func__);
     // TODO seems like that David is using previous_cpus as a bitmask.. 
     // TODO well this must be upgraded to a cpumask, declared as usigned long in task_struct
     struct list_head *iter;
@@ -8472,7 +8471,6 @@ extern struct list_head rlist_head;
         cpuid = objPtr->_data._processor;
         pcpum = &(objPtr->_data._cpumask);
        if (cpumask_test_cpu(cpu, pcpum)) {
-       printk(KERN_ALERT"%s: cpuid {%d} \n",cpuid);
                if ( bitmap_intersects(cpumask_bits(pcpum),
                                       &(task->previous_cpus),
                                       (sizeof(unsigned long)*8)) )
@@ -8493,14 +8491,16 @@ extern struct list_head rlist_head;
  */
 void process_server_do_return_disposition(void) {
 
-    PSPRINTK("%s\n",__func__);
     int return_disposition = current->return_disposition;
+
+    //printk("%s disp{%d} \n",__func__,return_disposition);
     // Reset the return disposition
     current->return_disposition = RETURN_DISPOSITION_NONE;
-    switch(current->return_disposition) {
+
+    switch(return_disposition) {
     case RETURN_DISPOSITION_NONE:
         printk("%s: ERROR, return disposition is none!\n",__func__);
-        break;    
+        break;   
     case RETURN_DISPOSITION_MIGRATE:
         // Nothing to do, already back-imported the
         // state in process_back_migration.  This will
index bc8b7c6..3da98f2 100644 (file)
@@ -73,9 +73,9 @@
 #include <linux/slab.h>
 #include <linux/init_task.h>
 #include <linux/process_server.h>
-#ifdef SUPPORT_FOR_CLUSTERING
+//#ifdef SUPPORT_FOR_CLUSTERING
 #include <linux/popcorn_cpuinfo.h>
-#endif
+//#endif
 
 #include <asm/tlb.h>
 #include <asm/irq_regs.h>
@@ -3289,9 +3289,11 @@ asmlinkage void schedule_tail(struct task_struct *prev)
 
        // Multikernel
     if(current->represents_remote) {
-        printk("Sleeping %d\n",current->pid);
+       dump_stack();
+        printk("Sleeping %d comm{%s} \n",current->pid,current->comm);
         set_current_state( TASK_INTERRUPTIBLE);
         schedule();
+        printk("after sleep in schdeule tail\n");
     }
 }
 
@@ -5564,6 +5566,30 @@ out_unlock:
        return retval;
 }
 
+int shadow_return_check(struct task_struct *tsk)
+{
+int spin =0;
+ if(current->pid == tsk->pid && (tsk->migration_state == 1 || tsk->represents_remote==1)){
+                do {
+                     spin = 0;
+                     schedule(); // this will save us from death
+                     if(current->return_disposition == RETURN_DISPOSITION_NONE) {
+                          __set_task_state(current,TASK_UNINTERRUPTIBLE);
+                           spin = 1;
+                       }
+                  } while (spin);
+            // We are here because of either the task is exiting,
+            // or because the task is migrating back.  Let's handle
+            // that now.  If we're migrating back, this function
+            // will return.  If we're exiting, we now die an honorable
+            // death and this function will not return.
+            process_server_do_return_disposition();
+
+            return 0;
+ }
+ else
+   return -1;
+}
 long sched_setaffinity(pid_t pid, const struct cpumask *in_mask)
 {
        cpumask_var_t cpus_allowed, new_mask;
@@ -5581,10 +5607,16 @@ long sched_setaffinity(pid_t pid, const struct cpumask *in_mask)
                put_online_cpus();
                return -ESRCH;
        }
+       spin_lock_irq(&(p->mig_lock));
+       p->migration_state=1;
+        spin_unlock_irq(&(p->mig_lock));
+       smp_mb();
        pid = current->pid;
-       printk("POP: current pid 2 \n",pid);
+if(current->tgroup_distributed == 1 || strcmp(current->comm,"is-gomp") == 0)
+   {   dump_stack();
+printk(KERN_ALERT"inside sched affinity pid{%d} c{%s} p{%d} state{%d}\n",current->pid,current->comm,p->pid,p->futex_state);
 
-// TODO migration must be removed from here
+}// TODO migration must be removed from here
     /*
      * Multikernel
      */
@@ -5622,27 +5654,25 @@ extern struct list_head rlist_head;
        // do the migration
             get_task_struct(p);
             rcu_read_unlock();
+printk(KERN_ALERT"before proce server {%d} i{%d} cpu{%d}\n",p->pid,i,current_cpu);
             ret =process_server_do_migration(p,i);
             put_task_struct(p);
             put_online_cpus();
             printk(KERN_ALERT"sched_setaffinity tsk{%d} state{%d} on run q{%d} RET{%d} current{%s} \n",p->pid,p->state,p->on_rq,ret,current->comm);
-            schedule(); // this will save us from death
-       /*      do {
-                    spin = 0;
-                    schedule(); // this will save us from death
-                    if(current->return_disposition == RETURN_DISPOSITION_NONE) {
-                         __set_task_state(current,TASK_UNINTERRUPTIBLE);
-                          spin = 1;
-                      }
-                 } while (spin);*/
-            // We are here because of either the task is exiting,
-            // or because the task is migrating back.  Let's handle
-            // that now.  If we're migrating back, this function
-            // will return.  If we're exiting, we now die an honorable
-            // death and this function will not return.
-            process_server_do_return_disposition();
-          
-            return 0;
+           spin_lock_irq(&(p->mig_lock));
+               p->migration_state=0;
+            spin_unlock_irq(&(p->mig_lock));
+          if(ret != PROCESS_SERVER_CLONE_FAIL)
+               return 0;
+               
+           if(shadow_return_check(p) == -1){
+               retval = 0;
+             }
+           else
+               return 0;
+           
+         
         }
     }
 }
@@ -5689,8 +5719,13 @@ out_unlock:
 out_free_cpus_allowed:
        free_cpumask_var(cpus_allowed);
 out_put_task:
+       spin_lock_irq(&(p->mig_lock));
+               p->migration_state=0;
+        spin_unlock_irq(&(p->mig_lock));
+
        put_task_struct(p);
        put_online_cpus();
+norm:
        return retval;
 }
 
@@ -5707,6 +5742,7 @@ static int get_user_cpu_mask(unsigned long __user *user_mask_ptr, unsigned len,
 
 /**
  * sys_sched_setaffinity - set the cpu affinity of a process
+
  * @pid: pid of the process
  * @len: length in bytes of the bitmask pointed to by user_mask_ptr
  * @user_mask_ptr: user-space pointer to the new cpu mask
@@ -5731,8 +5767,13 @@ long sched_getaffinity(pid_t pid, struct cpumask *mask)
 {
        struct task_struct *p;
        unsigned long flags;
-       int retval;
+       int retval,i;
 
+       struct list_head *iter;
+       _remote_cpu_info_list_t *objPtr;
+       struct cpumask *pcpum;
+       extern struct list_head rlist_head;
+       
        get_online_cpus();
        rcu_read_lock();
 
@@ -5744,10 +5785,25 @@ long sched_getaffinity(pid_t pid, struct cpumask *mask)
        retval = security_task_getscheduler(p);
        if (retval)
                goto out_unlock;
+    
 
        raw_spin_lock_irqsave(&p->pi_lock, flags);
        cpumask_and(mask, &p->cpus_allowed, cpu_online_mask);
        raw_spin_unlock_irqrestore(&p->pi_lock, flags);
+       
+       list_for_each(iter, &rlist_head) {
+        objPtr = list_entry(iter, _remote_cpu_info_list_t, cpu_list_member);
+        i = objPtr->_data._processor;
+        pcpum = &(objPtr->_data._cpumask);
+       cpumask_or(mask, pcpum, mask);
+       }
+
+       char buf_in[64];
+       memset(buf_in, 0, 64);
+       cpumask_scnprintf(buf_in, 63, mask);
+       printk("%s: in_mask %s \n",
+                __func__, buf_in);
+
 
 out_unlock:
        rcu_read_unlock();
index 92cebc0..f568bf9 100644 (file)
@@ -358,7 +358,7 @@ static int handle_remote_kill_request(struct pcn_kmsg_message* inc_msg) {
        return 0;
 }
 
-static int remote_kill_pid_info(int kernel, int sig, pid_t pid,
+int remote_kill_pid_info(int kernel, int sig, pid_t pid,
                struct siginfo *info) {
 
        int res = 0;
@@ -2120,6 +2120,8 @@ pid_t next_pid = -1;
 pid_t prev_pid = -1;
 pid_t origin_pid = -1;
 
+if(current->tgroup_distributed == 1)
+  printk(KERN_ALERT"signal {%d} for pid {%d} \n",sig,pid);
 
 if (pid > 0) {
        struct task_struct *p = pid_task(find_vpid(pid), PIDTYPE_PID);
@@ -2127,17 +2129,20 @@ if (pid > 0) {
                next_pid = p->next_pid;
                prev_pid = p->prev_pid;
                origin_pid = p->origin_pid;
+               if(p->tgroup_distributed == 1)
+                 printk(KERN_ALERT"signal {%d} for pid {%d} \n",sig,pid);
                }
 
        if(origin_pid!=-1 && next_pid != -1){
-                       /* struct task_struct *task = pid_task(find_vpid(pid), PIDTYPE_PID);
-                        if(task){
-                        __set_task_state(task,TASK_INTERRUPTIBLE);}*/
-                        ret=0;
+                        ret=0; 
+               if(p->tgroup_distributed == 1 && p->state == TASK_UNINTERRUPTIBLE){
+                       printk(KERN_ALERT"%s:remote_kill pid{%d} c(%d} cpu{%d}\n",__func__,pid,ORIG_NODE(pid),_cpu);
+                       return remote_kill_pid_info( ORIG_NODE(next_pid),sig,next_pid,info);
+}      
        }
        else{
        rcu_read_lock();
-       ret = kill_pid_info(sig, info, find_vpid(pid));
+               ret = kill_pid_info(sig, info, find_vpid(pid));
        rcu_read_unlock();
        }
        /*mklinux_akshay*/
@@ -2905,6 +2910,37 @@ if (sigismember(&current->blocked, signr)) {
 return signr;
 }
 
+
+
+static void dump_regs(struct pt_regs* regs) {
+       unsigned long fs, gs;
+       printk(KERN_ALERT"DUMP REGS\n");
+       if(NULL != regs) {
+               printk(KERN_ALERT"r15{%lx}\n",regs->r15);
+               printk(KERN_ALERT"r14{%lx}\n",regs->r14);
+               printk(KERN_ALERT"r13{%lx}\n",regs->r13);
+               printk(KERN_ALERT"r12{%lx}\n",regs->r12);
+               printk(KERN_ALERT"r11{%lx}\n",regs->r11);
+               printk(KERN_ALERT"r10{%lx}\n",regs->r10);
+               printk(KERN_ALERT"r9{%lx}\n",regs->r9);
+               printk(KERN_ALERT"r8{%lx}\n",regs->r8);
+               printk(KERN_ALERT"bp{%lx}\n",regs->bp);
+               printk(KERN_ALERT"bx{%lx}\n",regs->bx);
+               printk(KERN_ALERT"ax{%lx}\n",regs->ax);
+               printk(KERN_ALERT"cx{%lx}\n",regs->cx);
+               printk(KERN_ALERT"dx{%lx}\n",regs->dx);
+               printk(KERN_ALERT"di{%lx}\n",regs->di);
+               printk(KERN_ALERT"orig_ax{%lx}\n",regs->orig_ax);
+               printk(KERN_ALERT"ip{%lx}\n",regs->ip);
+               printk(KERN_ALERT"cs{%lx}\n",regs->cs);
+               printk(KERN_ALERT"flags{%lx}\n",regs->flags);
+               printk(KERN_ALERT"sp{%lx}\n",regs->sp);
+               printk(KERN_ALERT"ss{%lx}\n",regs->ss);
+       }
+       rdmsrl(MSR_FS_BASE, fs);
+       rdmsrl(MSR_GS_BASE, gs);
+       printk(KERN_ALERT"fs{%lx}\n",fs);
+}
 int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
        struct pt_regs *regs, void *cookie) {
 struct sighand_struct *sighand = current->sighand;
@@ -3080,6 +3116,8 @@ for (;;) {
                 * first and our do_group_exit call below will use
                 * that value and ignore the one we pass it.
                 */
+               dump_stack();
+               dump_regs(task_pt_regs(current));
                do_coredump(info->si_signo, info->si_signo, regs);
        }
 
@@ -3604,7 +3642,7 @@ if(!p){
 }
 
 get_task_struct(p);
-printk(KERN_ALERT"%s: cpu {%d} pid{%d} tgid{%d} p{%d} \n",__func__,_cpu,pid,tgid,(!p)?0:1);
+printk(KERN_ALERT"%s:sent by{%s} pid{%d} from cpu {%d} for pid{%d} tgid{%d} p{%d} \n",__func__,current->comm,current->pid,_cpu,pid,tgid,(!p)?0:1);
 
 if(p && p->tgroup_distributed && !p->executing_for_remote){
        if(p->return_disposition == RETURN_DISPOSITION_NONE) {
@@ -3613,6 +3651,12 @@ if(p && p->tgroup_distributed && !p->executing_for_remote){
                rcu_read_unlock();
                return remote_do_send_specific(ORIG_NODE(p->next_pid),tgid,p->next_pid,sig,info);
        }
+       else if(p->state == TASK_UNINTERRUPTIBLE){
+       printk(KERN_ALERT"main scheduled to other kernel\n");
+               put_task_struct(p);     
+               rcu_read_unlock();
+       return remote_do_send_specific(ORIG_NODE(p->next_pid),tgid,p->next_pid,sig,info);
+       }
 }
 if (p && (tgid <= 0 || task_tgid_vnr(p) == tgid) || p->executing_for_remote) {
        error = check_kill_permission(sig, info, p);
index d084003..6413fa5 100644 (file)
@@ -238,10 +238,12 @@ fail:
  * do_remote - 1 = ask process_server to notify all remote thread members
  *             0 = do not
  */
-int do_mprotect(struct task_struct* task, unsigned long start, size_t len, unsigned long prot, int do_remote) {
+int do_mprotect(struct task_struct* task, struct mm_struct* mm, unsigned long start, size_t len, unsigned long prot, int do_remote) {
        unsigned long vm_flags, nstart, end, tmp, reqprot;
        struct vm_area_struct *vma, *prev;
+    struct mm_struct* task_mm = task? task->mm : mm;
        int error = -EINVAL;
+    unsigned long a;
        const int grows = prot & (PROT_GROWSDOWN|PROT_GROWSUP);
        prot &= ~(PROT_GROWSDOWN|PROT_GROWSUP);
        if (grows == (PROT_GROWSDOWN|PROT_GROWSUP)) /* can't be both */
@@ -258,21 +260,31 @@ int do_mprotect(struct task_struct* task, unsigned long start, size_t len, unsig
        if (!arch_validate_prot(prot))
                return -EINVAL;
 
+#ifdef PROCESS_SERVER_ENFORCE_VMA_MOD_ATOMICITY
+    if(do_remote) {
         //printk("%s: doing lock\n",__func__);
+#ifdef PROCESS_SERVER_USE_HEAVY_LOCK
+        process_server_acquire_heavy_lock();
 #elif defined(PROCESS_SERVER_USE_DISTRIBUTED_MM_LOCK)
         process_server_acquire_distributed_mm_lock();
+#else
+        process_server_acquire_page_lock_range(start,len);
+#endif
+    }
+#endif
+
        reqprot = prot;
        /*
         * Does the application expect PROT_READ to imply PROT_EXEC:
         */
-       if ((prot & PROT_READ) && (task->personality & READ_IMPLIES_EXEC))
+       if (task && (prot & PROT_READ) && (task->personality & READ_IMPLIES_EXEC))
                prot |= PROT_EXEC;
 
        vm_flags = calc_vm_prot_bits(prot);
 
-       down_write(&task->mm->mmap_sem);
+       down_write(&task_mm->mmap_sem);
 
-       vma = find_vma_prev(task->mm, start, &prev);
+       vma = find_vma_prev(task_mm, start, &prev);
        error = -ENOMEM;
        if (!vma)
                goto out;
@@ -334,17 +346,27 @@ int do_mprotect(struct task_struct* task, unsigned long start, size_t len, unsig
                }
        }
 out:
-       up_write(&task->mm->mmap_sem);
+       up_write(&task_mm->mmap_sem);
 
     /*
      * Multikernel.  Change remote mappings as well before returning.
      */
-    if(!error && do_remote) {
+    if(!error && do_remote && task) {
         process_server_do_mprotect(task,start,len,prot);
     }
 
+#ifdef PROCESS_SERVER_ENFORCE_VMA_MOD_ATOMICITY
+    if(do_remote) {
+#ifdef PROCESS_SERVER_USE_HEAVY_LOCK
+        process_server_release_heavy_lock();
 #elif defined(PROCESS_SERVER_USE_DISTRIBUTED_MM_LOCK)
         process_server_release_distributed_mm_lock();
+#else
+        process_server_release_page_lock_range(start,len);
+#endif
+    }
+#endif
+
        return error;
 
 }
@@ -352,5 +374,5 @@ out:
 SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len,
                unsigned long, prot)
 {
-    return do_mprotect(current, start, len, prot, 1);
+    return do_mprotect(current, current->mm, start, len, prot, 1);
 }
index 4cdcc36..1c4373b 100644 (file)
@@ -432,10 +432,52 @@ unsigned long do_mremap(unsigned long addr,
        struct vm_area_struct *vma;
        unsigned long ret = -EINVAL;
        unsigned long charged = 0;
+    int original_enable_distributed_munmap = current->enable_distributed_munmap;
+    unsigned long a;
+    current->enable_distributed_munmap = 0;
+
+    // This is kind of tricky.  We have to lock the old range
+    // and the new range.
+    // Also, recursion is not an issue for mremap, since 
+    // process_server does not ever attempt to do distributed
+    // remaps, it is naughty, and just does a distributed
+    // munmap (except locally).  That should probably change.
+#ifdef PROCESS_SERVER_ENFORCE_VMA_MOD_ATOMICITY
     up_write(&mm->mmap_sem);
+#ifdef PROCESS_SERVER_USE_HEAVY_LOCK
+    process_server_acquire_heavy_lock();
 #elif defined(PROCESS_SERVER_USE_DISTRIBUTED_MM_LOCK)
     process_server_acquire_distributed_mm_lock();
+#else 
+    {
+    unsigned long old_start = addr;
+    unsigned long old_end   = addr + old_len;
+    unsigned long new_start = new_addr;
+    unsigned long new_end   = new_addr + new_len;
+    if(old_end <= new_start || new_end <= old_start) {
+        process_server_acquire_page_lock_range(old_start,old_len);
+        process_server_acquire_page_lock_range(new_start,new_len);
+    } else {
+        unsigned long min_start = old_start < new_start? old_start : new_start;
+        unsigned long max_end   = old_end > new_end? old_end : new_end;
+        process_server_acquire_page_lock_range(min_start,max_end - min_start);
+    }
+    }
+#endif
     down_write(&mm->mmap_sem);
+#endif
+
+    // Pull in all remote mappings so nothing is lost later.
+    for(a = addr & PAGE_MASK; a < addr + old_len; a+= PAGE_SIZE) {
+        struct vm_area_struct *vma_out = NULL;
+        process_server_pull_remote_mappings(current->mm,
+                                            NULL,
+                                            a,
+                                            NULL,
+                                            &vma_out,
+                                            NULL);
+
+    }
 
        if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
                goto out;
@@ -537,14 +579,41 @@ unsigned long do_mremap(unsigned long addr,
          * operation, and notify all remotes of a munmap.  If they want to access
          * the new space, they will fault and re-acquire the mapping.
          */
-        process_server_do_munmap(mm, vma, addr, old_len);
+        current->enable_distributed_munmap = original_enable_distributed_munmap;
+        process_server_do_munmap(mm, addr, old_len);
+        process_server_do_munmap(mm, new_addr, new_len);
+        current->enable_distributed_munmap = 0;
 
        }
 out:
        if (ret & ~PAGE_MASK)
                vm_unacct_memory(charged);
+#ifdef PROCESS_SERVER_ENFORCE_VMA_MOD_ATOMICITY
+#ifdef PROCESS_SERVER_USE_HEAVY_LOCK
+    process_server_release_heavy_lock();
 #elif defined(PROCESS_SERVER_USE_DISTRIBUTED_MM_LOCK)
     process_server_release_distributed_mm_lock();
+#else
+    {
+    unsigned long old_start = addr;
+    unsigned long old_end   = addr + old_len;
+    unsigned long new_start = new_addr;
+    unsigned long new_end   = new_addr + new_len;
+    if(old_end <= new_start || new_end <= old_start) {
+        process_server_release_page_lock_range(old_start,old_len);
+        process_server_release_page_lock_range(new_start,new_len);
+    } else {
+        unsigned long min_start = old_start < new_start? old_start : new_start;
+        unsigned long max_end   = old_end > new_end? old_end : new_end;
+        process_server_release_page_lock_range(min_start,max_end - min_start);
+    }
+
+    }
+#endif
+#endif
+
+    current->enable_distributed_munmap = original_enable_distributed_munmap;
+
        return ret;
 }
 
index c9e671e..3bc5f41 100644 (file)
@@ -1,9 +1,8 @@
 /*
  * Inter-kernel messaging support for Popcorn
  *
- * Antonio Barbalace, David Katz, Marina Sadini 2014
- * Antonio Barbalace, Marina Sadini, Phil Wilshire 2013
- * Ben Shelton 2012 - 2013
+ * Current ver: Antonio Barbalace, Phil Wilshire 2013
+ * First ver: Ben Shelton <beshelto@vt.edu> 2013
  */
 
 #include <linux/irq.h>
@@ -29,7 +28,7 @@
 #define LOGLEN 4
 #define LOGCALL 32
 
-#define KMSG_VERBOSE  0 
+#define KMSG_VERBOSE 0
 
 #if KMSG_VERBOSE
 #define KMSG_PRINTK(fmt, args...) printk("%s: " fmt, __func__, ##args)
 #define KMSG_PRINTK(...) ;
 #endif
 
-/*
- * MAX_LOOPS must be calibrated on each architecture. Is difficult to give a
- * good estimation for this parameter. Worst case must be equal or inferior to
- * the minimum time we will be blocked for a call to schedule_timeout
- */
-#define MAX_LOOPS 12345
-#define MAX_LOOPS_JIFFIES (MAX_SCHEDULE_TIMEOUT)
 
 #define MCAST_VERBOSE 0
 
@@ -95,18 +87,20 @@ struct workqueue_struct *messaging_wq;
 
 /* RING BUFFER */
 
-//#define RB_SHIFT 6
-//#define RB_SIZE (1 << RB_SHIFT)
-//#define RB_MASK ((1 << RB_SHIFT) - 1)
-
-#define RB_SIZE PCN_KMSG_RBUF_SIZE
-#define RB_MASK (RB_SIZE - 1)
+#define RB_SHIFT 6
+#define RB_SIZE (1 << RB_SHIFT)
+#define RB_MASK ((1 << RB_SHIFT) - 1)
 
 #define PCN_DEBUG(...) ;
 //#define PCN_WARN(...) printk(__VA_ARGS__)
 #define PCN_WARN(...) ;
 #define PCN_ERROR(...) printk(__VA_ARGS__)
 
+unsigned long long total_sleep_win_put = 0;
+unsigned int sleep_win_put_count = 0;
+unsigned long long total_sleep_win_get = 0;
+unsigned int sleep_win_get_count = 0;
+
 struct pcn_kmsg_hdr log_receive[LOGLEN];
 struct pcn_kmsg_hdr log_send[LOGLEN];
 int log_r_index=0;
@@ -117,13 +111,8 @@ int log_f_index=0;
 int log_f_sendindex=0;
 void * log_function_send[LOGCALL];
 
-#define SIZE_RANGES 7
-unsigned int large_message_sizes[(SIZE_RANGES +1)];
-unsigned int large_message_count[(SIZE_RANGES +1)];
-unsigned int type_message_count[PCN_KMSG_TYPE_MAX];
-
 /* From Wikipedia page "Fetch and add", modified to work for u64 */
-/*static inline unsigned long fetch_and_add(volatile unsigned long * variable, 
+static inline unsigned long fetch_and_add(volatile unsigned long * variable, 
                                          unsigned long value)
 {
        asm volatile( 
@@ -132,8 +121,7 @@ unsigned int type_message_count[PCN_KMSG_TYPE_MAX];
                     : "a" (value), "m" (*variable)  //Input
                     :"memory" );
        return value;
-}*/
-#define fetch_and_add xadd_sync
+}
 
 static inline unsigned long win_inuse(struct pcn_kmsg_window *win) 
 {
@@ -145,7 +133,7 @@ static inline int win_put(struct pcn_kmsg_window *win,
                          int no_block) 
 {
        unsigned long ticket;
-       unsigned long loop;
+    unsigned long long sleep_start;
 
        /* if we can't block and the queue is already really long, 
           return EAGAIN */
@@ -159,33 +147,25 @@ static inline int win_put(struct pcn_kmsg_window *win,
        PCN_DEBUG(KERN_ERR "%s: ticket = %lu, head = %lu, tail = %lu\n", 
                 __func__, ticket, win->head, win->tail);
 
-       KMSG_PRINTK("%s: ticket = %lu, head = %lu, tail = %lu buffer.lt = %lu diff = %lu\n",
-                        __func__, ticket, win->head, win->tail,win->buffer[ticket%PCN_KMSG_RBUF_SIZE].last_ticket, (ticket - PCN_KMSG_RBUF_SIZE));
+       KMSG_PRINTK("%s: ticket = %lu, head = %lu, tail = %lu\n",
+                        __func__, ticket, win->head, win->tail);
 
        who_is_writing= ticket;
        /* spin until there's a spot free for me */
        //while (win_inuse(win) >= RB_SIZE) {}
        //if(ticket>=PCN_KMSG_RBUF_SIZE){
-       //}
-       loop=0;  
-       if(ticket>=PCN_KMSG_RBUF_SIZE){
-               while( (win->buffer[ticket%PCN_KMSG_RBUF_SIZE].last_ticket
-                               != (ticket - PCN_KMSG_RBUF_SIZE)) ) {
-                       pcn_cpu_relax();
+    sleep_start = native_read_tsc();
+               while((win->buffer[ticket%PCN_KMSG_RBUF_SIZE].last_ticket != ticket-PCN_KMSG_RBUF_SIZE)) {
+                       //pcn_cpu_relax();
                        //msleep(1);
-                       if ( !(++loop % MAX_LOOPS) )
-                               schedule_timeout(MAX_LOOPS_JIFFIES);
                }
-       }
-       /* the following it is always false because add is after ready=0*/
-       //loop=0;
-       while( win->buffer[ticket%PCN_KMSG_RBUF_SIZE].ready!=0 ) {
-               pcn_cpu_relax();
-               //msleep(1);
-               if ( !(++loop % MAX_LOOPS) )
-                       schedule_timeout(MAX_LOOPS_JIFFIES);
-       }
-       
+               while(  win->buffer[ticket%PCN_KMSG_RBUF_SIZE].ready!=0){
+                       //pcn_cpu_relax();
+                       //msleep(1);
+               }
+    total_sleep_win_put += native_read_tsc() - sleep_start;
+    sleep_win_put_count++;
+       //}
        /* insert item */
        memcpy(&win->buffer[ticket%PCN_KMSG_RBUF_SIZE].payload,
               &msg->payload, PCN_KMSG_PAYLOAD_SIZE);
@@ -218,39 +198,52 @@ static inline int win_get(struct pcn_kmsg_window *win,
                          struct pcn_kmsg_reverse_message **msg) 
 {
        struct pcn_kmsg_reverse_message *rcvd;
-       unsigned long loop;
+    unsigned long long sleep_start;
 
        if (!win_inuse(win)) {
+
                KMSG_PRINTK("nothing in buffer, returning...\n");
                return -1;
        }
 
-       KMSG_PRINTK("reached win_get, head %lu, tail %lu\n", win->head, win->tail);
-       rcvd =(struct pcn_kmsg_reverse_message*) &(win->buffer[win->tail % PCN_KMSG_RBUF_SIZE]);
+       KMSG_PRINTK("reached win_get, head %lu, tail %lu\n", 
+                   win->head, win->tail);      
 
        /* spin until entry.ready at end of cache line is set */
-       loop=0;
+       rcvd =(struct pcn_kmsg_reverse_message*) &(win->buffer[win->tail % PCN_KMSG_RBUF_SIZE]);
+       //KMSG_PRINTK("%s: Ready bit: %u\n", __func__, rcvd->hdr.ready);
+
+    sleep_start = native_read_tsc();
        while (!rcvd->ready) {
-               pcn_cpu_relax();
+
+               //pcn_cpu_relax();
                //msleep(1);
-               if ( !(++loop % MAX_LOOPS) )
-                       schedule_timeout(MAX_LOOPS_JIFFIES);
+
        }
+    total_sleep_win_get += native_read_tsc() - sleep_start;
+    sleep_win_get_count++;
 
-       /* statistics */
-       memcpy(&(log_receive[log_r_index%LOGLEN]),
-              &(rcvd->hdr),
-              sizeof(struct pcn_kmsg_hdr));
+       // barrier here?
+       pcn_barrier();
+
+       //log_receive[log_r_index%LOGLEN]=rcvd->hdr;
+       memcpy(&(log_receive[log_r_index%LOGLEN]),&(rcvd->hdr),sizeof(struct pcn_kmsg_hdr));
        log_r_index++;
-       msg_get++;
 
-       *msg = rcvd;
+       //rcvd->hdr.ready = 0;
+
+       *msg = rcvd;    
+msg_get++;
+
+
+
        return 0;
 }
 
-/*static inline void win_advance_tail(struct pcn_kmsg_window *win) 
-{ win->tail++; }
-*/
+static inline void win_advance_tail(struct pcn_kmsg_window *win) 
+{
+       win->tail++;
+}
 
 /* win_enable_int
  * win_disable_int
@@ -478,14 +471,18 @@ static int pcn_read_proc(char *page, char **start, off_t off, int count, int *eo
        char *p= page;
     int len, i, idx;
 
-       p += sprintf(p, "get: %ld\n", msg_get);
-        p += sprintf(p, "put: %ld\n", msg_put);
-    for (i =0; i<(SIZE_RANGES +1); i++)
-      p +=sprintf (p,"%u: %u\n", large_message_sizes[i], large_message_count[i]);
-    
-    for (i =0; i<PCN_KMSG_TYPE_MAX; i++)
-      p +=sprintf (p, "t%u: %u\n", i, type_message_count[i]);
-    
+    p += sprintf(p, "Sleep in win_put[total,count,avg] = [%llx,%lx,%llx]\n",
+                    total_sleep_win_put,
+                    sleep_win_put_count,
+                    sleep_win_put_count? total_sleep_win_put/sleep_win_put_count:0);
+    p += sprintf(p, "Sleep in win_get[total,count,avg] = [%llx,%lx,%llx]\n",
+                    total_sleep_win_get,
+                    sleep_win_get_count,
+                    sleep_win_get_count? total_sleep_win_get/sleep_win_get_count:0);
+
+       p += sprintf(p, "messages get: %ld\n", msg_get);
+        p += sprintf(p, "messages put: %ld\n", msg_put);
+
     idx = log_r_index;
     for (i =0; i>-LOGLEN; i--)
        p +=sprintf (p,"r%d: from%d type%d %1d:%1d:%1d seq%d\n",
@@ -499,7 +496,7 @@ static int pcn_read_proc(char *page, char **start, off_t off, int count, int *eo
                        (idx+i),(int) log_send[(idx+i)%LOGLEN].from_cpu, (int)log_send[(idx+i)%LOGLEN].type,
                        (int) log_send[(idx+i)%LOGLEN].is_lg_msg, (int)log_send[(idx+i)%LOGLEN].lg_start,
                        (int) log_send[(idx+i)%LOGLEN].lg_end, (int) log_send[(idx+i)%LOGLEN].lg_seqnum );
-/*
+
     idx = log_f_index;
         for (i =0; i>-LOGCALL; i--)
                p +=sprintf (p,"f%d: %pB\n",
@@ -512,7 +509,7 @@ static int pcn_read_proc(char *page, char **start, off_t off, int count, int *eo
 
         for(i=0; i<PCN_KMSG_RBUF_SIZE; i++)
                p +=sprintf (p,"second_buffer[%i]=%i\n",i,rkvirt[my_cpu]->second_buffer[i]);
-*/
+
 
        len = (p -page) - off;
        if (len < 0)
@@ -522,20 +519,6 @@ static int pcn_read_proc(char *page, char **start, off_t off, int count, int *eo
        return len;
 }
 
-static int pcn_write_proc (struct file *file, const char __user *buffer, unsigned long count, void *data)
-{
-  int i;
-       msg_get=0;
-       msg_put=0;
-       memset(large_message_count, 0, sizeof(int)*(SIZE_RANGES +1));
-       memset(large_message_sizes, 0, sizeof(int)*(SIZE_RANGES +1));
-       for (i=0; i<SIZE_RANGES; i++)
-         large_message_sizes[i] = ((i+1)*PCN_KMSG_PAYLOAD_SIZE);
-       large_message_sizes[SIZE_RANGES] = ~0;
-       memset(type_message_count, 0, sizeof(int)*PCN_KMSG_TYPE_MAX);
-       return count;
-}
-
 static int __init pcn_kmsg_init(void)
 {
        int rc,i;
@@ -544,11 +527,8 @@ static int __init pcn_kmsg_init(void)
        struct boot_params *boot_params_va;
 
        KMSG_INIT("entered\n");
-#ifndef SUPPORT_FOR_CLUSTERING
-       my_cpu= smp_processor_id();
-#else
-       my_cpu = cpumask_first(cpu_present_mask);
-#endif
+
+       my_cpu = raw_smp_processor_id();
        
        printk("%s: THIS VERSION DOES NOT SUPPORT CACHE ALIGNED BUFFERS\n",
               __func__);
@@ -587,14 +567,14 @@ static int __init pcn_kmsg_init(void)
        /* Register softirq handler now kworker */
        KMSG_INIT("Registering softirq handler...\n");
        //open_softirq(PCN_KMSG_SOFTIRQ, pcn_kmsg_action);
-       messaging_wq= create_singlethread_workqueue("messaging_wq");
+       messaging_wq= create_workqueue("messaging_wq");
        if (!messaging_wq) 
                printk("%s: create_workqueue(messaging_wq) ret 0x%lx ERROR\n",
                        __func__, (unsigned long)messaging_wq);
 
        /* Initialize work queue */
        KMSG_INIT("Initializing workqueue...\n");
-       kmsg_wq = create_singlethread_workqueue("kmsg_wq");
+       kmsg_wq = create_workqueue("kmsg_wq");
        if (!kmsg_wq)
                printk("%s: create_workqueue(kmsg_wq) ret 0x%lx ERROR\n",
                        __func__, (unsigned long)kmsg_wq);
@@ -632,10 +612,6 @@ static int __init pcn_kmsg_init(void)
                boot_params_va->pcn_kmsg_master_window = rkinfo_phys_addr;
                KMSG_INIT("boot_params virt %p phys %p\n",
                        boot_params_va, orig_boot_params);
-               
-               KMSG_INIT("LOOPS %ld, LOOPS_JIFFIES %ld, 1nsec %ld, 1usec %ld, 1msec %ld, 1jiffies %d %d\n",
-                         MAX_LOOPS, MAX_LOOPS_JIFFIES, nsecs_to_jiffies(1), usecs_to_jiffies(1), msecs_to_jiffies(1),
-                         jiffies_to_msecs(1), jiffies_to_usecs(1));
        }
        else {
                KMSG_INIT("Primary kernel rkinfo phys addr: 0x%lx\n", 
@@ -671,7 +647,6 @@ static int __init pcn_kmsg_init(void)
                return -1;
        }
 
-
        /* If we're not the master kernel, we need to check in */
        if (mklinux_boot) {
                rc = do_checkin();
@@ -682,16 +657,6 @@ static int __init pcn_kmsg_init(void)
                }
        } 
 
-
-       printk("PCN_KMSG_RBUF_SIZE %ld",PCN_KMSG_RBUF_SIZE);
-       /* proc interface for debugging and stats */
-       memset(large_message_count, 0, sizeof(int)*(SIZE_RANGES +1));
-       memset(large_message_sizes, 0, sizeof(int)*(SIZE_RANGES +1));
-       for (i=0; i<SIZE_RANGES; i++)
-         large_message_sizes[i] = ((i+1)*PCN_KMSG_PAYLOAD_SIZE);
-       large_message_sizes[SIZE_RANGES] = ~0;
-       memset(type_message_count, 0, sizeof(int)*PCN_KMSG_TYPE_MAX);
-
        memset(log_receive,0,sizeof(struct pcn_kmsg_hdr)*LOGLEN);
        memset(log_send,0,sizeof(struct pcn_kmsg_hdr)*LOGLEN);
        memset(log_function_called,0,sizeof(void*)*LOGCALL);
@@ -704,8 +669,6 @@ static int __init pcn_kmsg_init(void)
                return -ENOMEM;
        }
        res->read_proc = pcn_read_proc;
-       res->write_proc = pcn_write_proc;
-       
 
        return 0;
 }
@@ -753,7 +716,7 @@ static int __pcn_kmsg_send(unsigned int dest_cpu, struct pcn_kmsg_message *msg,
        struct pcn_kmsg_window *dest_window;
 
        if (unlikely(dest_cpu >= POPCORN_MAX_CPUS)) {
-               KMSG_PRINTK("Invalid destination CPU %d\n", dest_cpu);
+               KMSG_ERR("Invalid destination CPU %d\n", dest_cpu);
                return -1;
        }
 
@@ -765,7 +728,7 @@ static int __pcn_kmsg_send(unsigned int dest_cpu, struct pcn_kmsg_message *msg,
        }
 
        if (unlikely(!msg)) {
-               KMSG_PRINTK("Passed in a null pointer to msg!\n");
+               KMSG_ERR("Passed in a null pointer to msg!\n");
                return -1;
        }
 
@@ -773,7 +736,6 @@ static int __pcn_kmsg_send(unsigned int dest_cpu, struct pcn_kmsg_message *msg,
        msg->hdr.from_cpu = my_cpu;
 
        rc = win_put(dest_window, msg, no_block);
-type_message_count[msg->hdr.type]++;
 
        if (rc) {
                if (no_block && (rc == EAGAIN)) {
@@ -866,10 +828,6 @@ int pcn_kmsg_send_long(unsigned int dest_cpu,
                if(ret!=0)
                        return ret;
        }
-       
-       /* statistics */
-       num_chunks = payload_size / PCN_KMSG_PAYLOAD_SIZE;
-       large_message_count[((num_chunks < SIZE_RANGES) ? num_chunks : SIZE_RANGES)]++;
 
        return 0;
 }
@@ -1029,7 +987,6 @@ static int process_large_message(struct pcn_kmsg_reverse_message *msg)
                /* copy first chunk of message */
                memcpy((unsigned char *) &lmsg->payload,
                       &msg->payload, PCN_KMSG_PAYLOAD_SIZE);
-                
 
                if (msg->hdr.lg_end) {
                        KMSG_PRINTK("NOTE: Long message of length 1 received; this isn't efficient!\n");
@@ -1072,8 +1029,8 @@ next:
 
                if (msg->hdr.lg_end) {
                        KMSG_PRINTK("Last fragment in series...\n");
-                       KMSG_PRINTK("from_cpu %d, type %d, prio %d-mprio%d\n",
-                                   lmsg->hdr.from_cpu, lmsg->hdr.type, lmsg->hdr.prio,msg->hdr.prio);
+                       KMSG_PRINTK("from_cpu %d, type %d, prio %d\n",
+                                   lmsg->hdr.from_cpu, lmsg->hdr.type, lmsg->hdr.prio);
                        /* add to appropriate list */
 #ifdef BEN_VERSION
                        rc = msg_add_list(lg_buf[msg->hdr.from_cpu]);
@@ -1119,19 +1076,18 @@ static int process_small_message(struct pcn_kmsg_reverse_message *msg)
        return work_done;
 }
 
-static int poll_handler_check=0;
 static int pcn_kmsg_poll_handler(void)
 {
        struct pcn_kmsg_reverse_message *msg;
        struct pcn_kmsg_window *win = rkvirt[my_cpu]; // TODO this will not work for clustering
        int work_done = 0;
 
-       poll_handler_check++;
-       if (poll_handler_check >1)
-               printk("poll_hanlder_check %d concurrent calls not supported\n", poll_handler_check);
+       KMSG_PRINTK("called\n");
 
 pull_msg:
        /* Get messages out of the buffer first */
+//#define PCN_KMSG_BUDGET 128
+       //while ((work_done < PCN_KMSG_BUDGET) && (!win_get(rkvirt[my_cpu], &msg))) {
        while (! win_get(win, &msg) ) {
                KMSG_PRINTK("got a message!\n");
 
@@ -1143,16 +1099,10 @@ pull_msg:
                        KMSG_PRINTK("message is a small message!\n");
                        work_done += process_small_message(msg);
                }
-
-               msg->ready = 0;
                pcn_barrier();
-               
-               fetch_and_add(&win->tail, 1); //win_advance_tail(win);
-               
-               // NOTE
-               // why you need the ready bit if you are incrementing the tail?
-               // can we increment the tail before signaling the ready bit?
-               // in that way we can support multiple calls to this function
+               msg->ready = 0;
+               //win_advance_tail(win);
+               fetch_and_add(&win->tail, 1);
        }
 
        win_enable_int(win);
@@ -1161,7 +1111,6 @@ pull_msg:
                goto pull_msg;
        }
 
-       poll_handler_check--;
        return work_done;
 }
 
index 74af8e0..e194f2c 100644 (file)
@@ -267,7 +267,7 @@ SYSCALL_DEFINE2(popcorn_test_kmsg, enum pcn_kmsg_test_op, op,
                        rc = pcn_kmsg_test_mcast_close(args);
                        break;
 #endif /* PCN_SUPPORT_MULTICAST */
-
+                       
                default:
                        TEST_ERR("invalid option %d\n", op);
                        return -1;
@@ -456,3 +456,4 @@ static int __init pcn_kmsg_test_init(void)
 }
 
 late_initcall(pcn_kmsg_test_init);
+