static void
umem_lockup(void)
{
	umem_cache_t *cp;

	(void) mutex_lock(&umem_init_lock);
	/*
	 * If another thread is busy initializing the library, we must
	 * wait for it to complete (by calling umem_init()) before allowing
	 * the fork() to proceed.
	 */
	if (umem_ready == UMEM_READY_INITING && umem_init_thr != thr_self()) {
		(void) mutex_unlock(&umem_init_lock);
		(void) umem_init();
		(void) mutex_lock(&umem_init_lock);
	}
	(void) mutex_lock(&umem_cache_lock);
	(void) mutex_lock(&umem_update_lock);
	(void) mutex_lock(&umem_flags_lock);

	umem_lockup_cache(&umem_null_cache);
	for (cp = umem_null_cache.cache_prev; cp != &umem_null_cache;
	    cp = cp->cache_prev)
		umem_lockup_cache(cp);

	umem_lockup_log_header(umem_transaction_log);
	umem_lockup_log_header(umem_content_log);
	umem_lockup_log_header(umem_failure_log);
	umem_lockup_log_header(umem_slab_log);

	(void) cond_broadcast(&umem_update_cv);

	vmem_sbrk_lockup();
	vmem_lockup();
}
Beispiel #2
0
const mdb_modinfo_t *
_mdb_init(void)
{
	if (umem_init() != 0)
		return (NULL);

	return (&modinfo);
}
Beispiel #3
0
vmem_t *
vmem_heap_arena(vmem_alloc_t **allocp, vmem_free_t **freep)
{
	static mutex_t arena_mutex = DEFAULTMUTEX;

	/*
	 * Allow the init thread through, block others until the init completes
	 */
	if (umem_ready != UMEM_READY && umem_init_thr != thr_self() &&
	    umem_init() == 0)
		return (NULL);

	(void) mutex_lock(&arena_mutex);
	if (vmem_heap == NULL)
		vmem_heap_init();
	(void) mutex_unlock(&arena_mutex);

	if (allocp != NULL)
		*allocp = vmem_heap_alloc;
	if (freep != NULL)
		*freep = vmem_heap_free;
	return (vmem_heap);
}
Beispiel #4
0
int32_t fork() {
    /* Time to... fork!
     * I had spent a long time preparing for this!
     * now I am done, it's time to start working on fork().
     */
    int32_t i;
    proc_t *newproc;

    /* create a new process structure: */
    newproc = kmalloc(sizeof(proc_t));
    if (newproc == NULL)
        return -1;

    /* set parent */
    newproc->parent = curproc;

    /* initialize descriptors: */
    newproc->plist.proc = newproc;
    newproc->sched.proc = newproc;
    newproc->irqd.proc  = newproc;
    newproc->semad.proc = newproc;

    /* create memory: */
    if (umem_init(&(newproc->umem))) {
        kfree(newproc);
        return -1; /* error. */
    }

    /* inherit parent's memory: */
    if (umem_copy(&(curproc->umem), &(newproc->umem))) {
        umem_free(&(newproc->umem));
        kfree(newproc);
        return -1; /* error. */
    }

    /* create a new kernel stack. */
    newproc->kstack = (unsigned char *) kmalloc(KERNEL_STACK_SIZE);
    if (newproc->kstack == NULL) {
        umem_free(&(newproc->umem));
        kfree(newproc);
        return -1; /* error. */
    }
    initproc->phy_stack_bot = arch_vmpage_getAddr(NULL, newproc->kstack);

    /* initialize kernel stack...
     * this invokes page faults to allocate memory for
     * the stack early.
     */
    for (i = 0; i < KERNEL_STACK_SIZE; i++)
        newproc->kstack[i] = 0;

    /* copy context from parent's stack to child's stack: */
    copy_context(newproc);

    /* copy the set of file descriptors: */
    for (i = 0; i < FD_MAX; i++) {
        if (curproc->file[i] == NULL) {
            newproc->file[i] = NULL;
        } else {
            curproc->file[i]->fcount++;
            newproc->file[i] = curproc->file[i];
        }
    }

    /* inherit the current working directory: */
    curproc->cwd->fcount++;
    newproc->cwd = curproc->cwd;

    /* set pid: */
    newproc->pid = ++last_pid;

    /* inform the scheduler that this is a just-forked process: */
    newproc->after_fork = 1;

    /* initialize inbox */
    newproc->inbox_lock = 0;
    newproc->blocked_for_msg = 0;
    linkedlist_init(&(newproc->inbox));

    /* children */
    newproc->blocked_for_child = 0;

    /* not blocked */
    newproc->blocked = 0;
    newproc->lock_to_unlock = NULL;

    /* exit status: */
    newproc->terminated = 0;
    newproc->status = 0;

    /* add the new process to the list of processes: */
    linkedlist_addlast((linkedlist*)&proclist, (linknode*)&(newproc->plist));

    /* add to scheduler's queue: */
    linkedlist_addlast((linkedlist*)&q_ready, (linknode*)&(newproc->sched));

    /* call the scheduler */
    scheduler();

    /* return */
    if (curproc == newproc) {
        return 0;
    } else {
        return newproc->pid;
    }

}
Beispiel #5
0
void proc_init() {

    /* Process Manager Initialization */
    int32_t i, err = 0;
    char *initpath = "/bin/init";

    /* (I) Initialize linked lists:  */
    /* ----------------------------- */
    linkedlist_init((linkedlist *) &proclist);
    linkedlist_init((linkedlist *) &q_ready);
    linkedlist_init((linkedlist *) &q_blocked);

    /* (II) Create "init" process:  */
    /* ---------------------------- */
    /* Allocate memory for process structures: */
    initproc = (proc_t *) kmalloc(sizeof(proc_t));

    /* set parent */
    initproc->parent = NULL;

    /* initialize descriptors: */
    initproc->plist.proc = initproc;
    initproc->sched.proc = initproc;
    initproc->irqd.proc  = initproc;

    /* Set "init" pid <1>: */
    initproc->pid = 1;

    /* Add it to process list: */
    linkedlist_addlast((linkedlist *) &proclist,
                       (linknode   *) &(initproc->plist));

    /* Kernel-mode stack: */
    initproc->kstack = kernel_stack;

    /* User memory: */
    umem_init(&(initproc->umem));

    /* initialize file descriptors: */
    for(i = 0; i < FD_MAX; i++)
        initproc->file[i] = NULL;

    /* current working directory: */
    file_open("/", 0, &(initproc->cwd));

    /* not forked: */
    initproc->after_fork = 0;

    /* initialize inbox */
    initproc->inbox_lock = 0;
    initproc->blocked_for_msg = 0;
    linkedlist_init(&(initproc->inbox));

    /* children */
    initproc->blocked_for_child = 0;

    /* not blocked */
    initproc->blocked = 0;

    /* exit status: */
    initproc->terminated = 0;
    initproc->status = 0;

    /* (III) Run the "init" process:  */
    /* ------------------------------ */
    curproc = initproc; /* init process is running! */
    arch_vmswitch(&(initproc->umem));

    /* (IV) Enable multitasking:  */
    /* -------------------------- */
    scheduler_enabled = 1; /* start multitasking! */

    /* (V) Open console streams:  */
    /* -------------------------- */
    /* create device file for console: */
    mknod("/dev/console", FT_SPECIAL, system_console->devid);

    /* open console file: */
    open("/dev/console", 0); /* this will open the file at fd "0". */
    dup(0); /* duplicate at fd "1". */
    dup(0); /* duplicate at fd "2". */

    /* (VI) Execute "init" program to initialize the operating system:  */
    /* ---------------------------------------------------------------- */
    printk("Executing \"%s\" ...\n\n", initpath);
    printk("%a", 0x0E);
    execve(initpath, 0, 0);
    printk("FATAL: Error happened during execution.\n");
    idle();

}