OpenCores
URL https://opencores.org/ocsvn/c0or1k/c0or1k/trunk

Subversion Repositories c0or1k

[/] [c0or1k/] [trunk/] [conts/] [posix/] [mm0/] [mm/] [clone.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 drasko
/*
2
 * Forking and cloning threads, processes
3
 *
4
 * Copyright (C) 2008 Bahadir Balban
5
 */
6
#include L4LIB_INC_ARCH(syslib.h)
7
#include <l4lib/ipcdefs.h>
8
#include <l4lib/exregs.h>
9
#include <l4/api/errno.h>
10
#include <l4/api/thread.h>
11
#include <syscalls.h>
12
#include <vm_area.h>
13
#include <task.h>
14
#include <mmap.h>
15
#include <shm.h>
16
#include <test.h>
17
#include <clone.h>
18
 
19
int sys_fork(struct tcb *parent)
20
{
21
        int err;
22
        struct tcb *child;
23
        struct exregs_data exregs;
24
        struct task_ids ids;
25
 
26
        /* Make all shadows in this task read-only */
27
        vm_freeze_shadows(parent);
28
 
29
        /*
30
         * Create a new L4 thread with parent's page tables
31
         * kernel stack and kernel-side tcb copied
32
         */
33
        if (IS_ERR(child = task_create(parent, &ids,
34
                                       TCB_NO_SHARING,
35
                                       TC_COPY_SPACE)))
36
                return (int)child;
37
 
38
        /* Set child's fork return value to 0 */
39
        memset(&exregs, 0, sizeof(exregs));
40
        exregs_set_mr(&exregs, MR_RETURN, 0);
41
 
42
        /* Set child's new utcb address set by task_create() */
43
        BUG_ON(!child->utcb_address);
44
        exregs_set_utcb(&exregs,
45
                        child->utcb_address);
46
 
47
        /* Do the actual exregs call to c0 */
48
        if ((err = l4_exchange_registers(&exregs,
49
                                         child->tid)) < 0)
50
                BUG();
51
 
52
        /* Add child to global task list */
53
        global_add_task(child);
54
 
55
        /* Start forked child. */
56
        l4_thread_control(THREAD_RUN, &ids);
57
 
58
        /* Return child tid to parent */
59
        return child->tid;
60
}
61
 
62
int do_clone(struct tcb *parent, unsigned long child_stack,
63
             unsigned int flags, unsigned int sysflags)
64
{
65
        struct exregs_data exregs;
66
        struct task_ids ids;
67
        struct tcb *child;
68
        int err;
69
 
70
        if (IS_ERR(child = task_create(parent, &ids,
71
                                       flags,
72
                                       sysflags)))
73
                return (int)child;
74
 
75
        /* Set up child stack marks with given stack argument */
76
        child->stack_end = child_stack;
77
        child->stack_start = 0;
78
 
79
        memset(&exregs, 0, sizeof(exregs));
80
 
81
        /* Set child's stack pointer */
82
        exregs_set_stack(&exregs, child_stack);
83
 
84
        /* Set child's clone return value to 0 */
85
        exregs_set_mr(&exregs, MR_RETURN, 0);
86
        BUG_ON(!child->utcb_address);
87
        exregs_set_utcb(&exregs, child->utcb_address);
88
 
89
        /* Do the actual exregs call to c0 */
90
        if ((err = l4_exchange_registers(&exregs,
91
                                         child->tid)) < 0)
92
                BUG();
93
 
94
        /* Add child to global task list */
95
        global_add_task(child);
96
 
97
        /* Start cloned child. */
98
        l4_thread_control(THREAD_RUN, &ids);
99
 
100
        /* Return child tid to parent */
101
        return child->tid;
102
}
103
 
104
 
105
int sys_clone(struct tcb *parent,
106
              void *child_stack,
107
              unsigned int clone_flags)
108
{
109
        unsigned int flags = 0;
110
        unsigned int sysflags = 0;
111
 
112
        if (!child_stack)
113
                return -EINVAL;
114
        BUG_ON((unsigned long)child_stack < 0x10000);
115
 
116
        if (clone_flags & CLONE_VM) {
117
                flags |= TCB_SHARED_VM;
118
                sysflags |= TC_SHARE_SPACE;
119
        }
120
        if (clone_flags & CLONE_FS)
121
                flags |= TCB_SHARED_FS;
122
        if (clone_flags & CLONE_FILES)
123
                flags |= TCB_SHARED_FILES;
124
        if (clone_flags & CLONE_THREAD) {
125
                flags |= TCB_SHARED_TGROUP;
126
                sysflags |= TC_SHARE_GROUP;
127
        }
128
        if (clone_flags & CLONE_PARENT)
129
                flags |= TCB_SHARED_PARENT;
130
 
131
        return do_clone(parent,
132
                        (unsigned long)child_stack,
133
                        flags, sysflags);
134
}
135
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.