Kernel messages infrastructure
[akaros.git] / kern / src / frontend.c
index d7bc5d9..7781399 100644 (file)
 #include <frontend.h>
 #include <syscall.h>
 #include <smp.h>
+#include <slab.h>
 
 volatile int magic_mem[10];
 
 void
 frontend_proc_init(struct proc *SAFE p)
 {
+#ifdef __CONFIG_APPSERVER__
        pid_t parent_id = p->ppid, id = p->pid;
        int32_t errno;
        if(frontend_syscall(parent_id,APPSERVER_SYSCALL_proc_init,id,0,0,0,&errno))
                panic("Front-end server couldn't initialize new process!");
+#endif
 }
 
 void
 frontend_proc_free(struct proc *SAFE p)
 {
+#ifdef __CONFIG_APPSERVER__
        int32_t errno;
        if(frontend_syscall(0,APPSERVER_SYSCALL_proc_free,p->pid,0,0,0,&errno))
                panic("Front-end server couldn't free process!");
+#endif
 }
 
 void* user_memdup(struct proc* p, const void* va, int len)
@@ -124,6 +129,13 @@ void* kmalloc_errno(int len)
        return kva;
 }
 
+struct kmem_cache* struct_file_cache;
+void file_init()
+{
+       struct_file_cache = kmem_cache_create("struct_file",
+                                             sizeof(struct file), 8, 0, 0, 0);
+}
+
 error_t file_read_page(struct file* f, physaddr_t pa, size_t pgoff)
 {
        int ret = frontend_syscall(0,APPSERVER_SYSCALL_pread,f->fd,pa,PGSIZE,
@@ -136,10 +148,16 @@ error_t file_read_page(struct file* f, physaddr_t pa, size_t pgoff)
 struct file* file_open_from_fd(struct proc* p, int fd)
 {
        struct file* f = NULL;
-       if(!(f = kmalloc(sizeof(struct file),0)))
+       if(!(f = kmem_cache_alloc(struct_file_cache,0)))
                goto out;
 
        f->fd = frontend_syscall(p->pid,APPSERVER_SYSCALL_kdup,fd,0,0,0,NULL);
+       if(f->fd == -1)
+       {
+               kmem_cache_free(struct_file_cache,f);
+               f = NULL;
+               goto out;
+       }
        spinlock_init(&f->lock);
        f->refcnt = 1;
 
@@ -162,11 +180,17 @@ struct file* file_open(const char* path, int oflag, int mode)
                path = memcpy(malloced,path,len);
        }
 
-       if(!(f = kmalloc(sizeof(struct file),0)))
+       if(!(f = kmem_cache_alloc(struct_file_cache,0)))
                goto out;
 
        f->fd = frontend_syscall(0,APPSERVER_SYSCALL_open,PADDR(path),
                                 oflag,mode,0,NULL);
+       if(f->fd == -1)
+       {
+               kmem_cache_free(struct_file_cache,f);
+               f = NULL;
+               goto out;
+       }
        spinlock_init(&f->lock);
        f->refcnt = 1;
 
@@ -191,7 +215,7 @@ void file_decref(struct file* f)
        {
                int ret = frontend_syscall(0,APPSERVER_SYSCALL_close,f->fd,0,0,0,NULL);
                assert(ret == 0);
-               kfree(f);
+               kmem_cache_free(struct_file_cache,f);
        }
        else
                spin_unlock(&f->lock);
@@ -209,13 +233,21 @@ int32_t frontend_syscall(pid_t pid, int32_t syscall_num,
                          uint32_t arg0, uint32_t arg1, 
                          uint32_t arg2, uint32_t arg3, int32_t* errno)
 {
+#ifndef __CONFIG_APPSERVER__
+       warn("No appserver support: either "
+            "don't make this syscall or enable the appserver!\n");
+       if(errno)
+               *errno = ENOSYS;
+       return -1;
+#endif
+
        static spinlock_t lock = SPINLOCK_INITIALIZER;
        int32_t ret;
 
        // only one frontend request at a time.
        // interrupts could try to do frontend requests,
        // which would deadlock, so disable them
-       spin_lock_irqsave(&lock);
+       spin_lock(&lock);
 
        // write syscall into magic memory
        magic_mem[7] = 0;
@@ -235,7 +267,7 @@ int32_t frontend_syscall(pid_t pid, int32_t syscall_num,
        if(errno)
                *errno = magic_mem[2];
 
-       spin_unlock_irqsave(&lock);
+       spin_unlock(&lock);
 
        return ret;
 }
@@ -252,7 +284,8 @@ void appserver_die(int code)
        int i;
        for(i = 0; i < num_cpus; i++)
                if(i != core_id())
-                       while(send_active_message(i,(amr_t)&__diediedie,(void*)code,0,0));
+                       while(send_kernel_message(i,(amr_t)&__diediedie,(void*)code,0,0,
+                                                 AMSG_IMMEDIATE));
 
        // just in case.
        __diediedie(0,0,code,0,0);