| 94 | ****************************************************************************/ |
| 95 | |
| 96 | FAR struct tcb_s *nxtask_setup_fork(start_t retaddr) |
| 97 | { |
| 98 | FAR struct tcb_s *ptcb = this_task(); |
| 99 | FAR struct tcb_s *parent; |
| 100 | FAR struct tcb_s *child; |
| 101 | FAR char **argv; |
| 102 | size_t stack_size; |
| 103 | uint8_t ttype; |
| 104 | int priority; |
| 105 | int ret; |
| 106 | |
| 107 | DEBUGASSERT(retaddr != NULL); |
| 108 | |
| 109 | /* Get the type of the fork'ed task (kernel or user) */ |
| 110 | |
| 111 | if ((ptcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL) |
| 112 | { |
| 113 | /* Fork'ed from a kernel thread */ |
| 114 | |
| 115 | ttype = TCB_FLAG_TTYPE_KERNEL; |
| 116 | parent = ptcb; |
| 117 | } |
| 118 | else |
| 119 | { |
| 120 | /* Fork'ed from a user task or pthread */ |
| 121 | |
| 122 | ttype = TCB_FLAG_TTYPE_TASK; |
| 123 | if ((ptcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_TASK) |
| 124 | { |
| 125 | parent = ptcb; |
| 126 | } |
| 127 | else |
| 128 | { |
| 129 | parent = nxsched_get_tcb(ptcb->group->tg_pid); |
| 130 | if (parent == NULL) |
| 131 | { |
| 132 | ret = -ENOENT; |
| 133 | goto errout; |
| 134 | } |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | /* Allocate a TCB for the child task. */ |
| 139 | |
| 140 | child = kmm_zalloc(sizeof(struct tcb_s)); |
| 141 | if (!child) |
| 142 | { |
| 143 | serr("ERROR: Failed to allocate TCB\n"); |
| 144 | ret = -ENOMEM; |
| 145 | goto errout; |
| 146 | } |
| 147 | |
| 148 | child->flags |= TCB_FLAG_FREE_TCB; |
| 149 | |
| 150 | /* Initialize the task join */ |
| 151 | |
| 152 | nxtask_joininit(child); |
| 153 |
no test coverage detected