Ejemplo n.º 1
0
Archivo: fork.c Proyecto: cod5/kielder
int Fork (void)
{
	struct Process *newproc;
	
	
	KPRINTF ("Fork()");
	
	if ((newproc = AllocProcess(PROC_TYPE_USER)) != NULL)
	{
		StrLCpy (newproc->exe_name, current_process->exe_name, PROC_NAME_SZ);
		
		if (*newproc->exe_name == '\0')
		{
			KPRINTF ("Fork() exe_name == 0");
			while(1) KWait(0);
		}
		
		
		if (DuplicateAddressSpace (&current_process->as, &newproc->as) == 0)
		{
			newproc->user_as = &newproc->as;
						
			if (0 == FSCreateProcess (current_process, newproc, current_process->current_dir, DUP_FD))
			{
				USigFork (current_process, newproc);
				
				if (ArchInitFork (newproc) == 0)
				{
					DisableInterrupts();
					newproc->state = PROC_STATE_READY;
					newproc->priority = 0;
					SchedReady (newproc);
					Reschedule();
					EnableInterrupts();
					
					return newproc->pid;
				}
				
				FSExitProcess (newproc);
			}
			
			FreeAddressSpace (&newproc->as);
		}
		
		FreeProcess (newproc);
	}
	
	
	return -1;
}
Ejemplo n.º 2
0
SYSCALL int Spawn (struct SpawnArgs *user_sa, void **user_segments, int segment_cnt)
{
    struct Process *proc, *current;
    void *segments[NSPAWNSEGMENTS];
    struct Segment *vs_ptrs[NSPAWNSEGMENTS];
    int h;  
    int t;
    struct SpawnArgs sa;
    
    
    current = GetCurrentProcess();
    
    if (!(current->flags & PROCF_FILESYS))
        return privilegeErr;
    
            
    if (segment_cnt < 1 || segment_cnt > NSPAWNSEGMENTS)
        return paramErr;

    CopyIn (&sa, user_sa, sizeof sa);
    CopyIn (segments, user_segments, sizeof (void *) * segment_cnt);

    if (free_handle_cnt < (1 + 3 + 1) || free_process_cnt < 1)
        return resourceErr;
    
    if (sa.namespace_handle == -1)
        return paramErr;

    if (FindHandle (current, sa.namespace_handle) == NULL)
        return paramErr;
    
    if (SegmentFindMultiple (vs_ptrs, segments, segment_cnt) < 0)
        return paramErr;
    
    DisablePreemption();
    
    h = AllocHandle();
    proc = AllocProcess();
    proc->handle = h;
    proc->flags = sa.flags & ~PROCF_SYSTEMMASK;


    proc->namespace_handle = sa.namespace_handle;
    handle_table[sa.namespace_handle].owner = proc;
    handle_table[sa.namespace_handle].flags |= HANDLEF_GRANTED_ONCE;
    
    proc->sighangup_handle = AllocHandle();
    SetObject (proc, proc->sighangup_handle, HANDLE_TYPE_SYSTEMEVENT, NULL);
    handle_table[proc->sighangup_handle].flags |= HANDLEF_GRANTED_ONCE;
    
    proc->sigterm_handle = AllocHandle();
    SetObject (proc, proc->sigterm_handle, HANDLE_TYPE_PROCESS, NULL);
    handle_table[proc->sigterm_handle].flags |= HANDLEF_GRANTED_ONCE;
    
    current->argv = sa.argv;
    current->argc = sa.argc;
    current->envv = sa.envv;
    current->envc = sa.envc;

    ArchAllocProcess(proc, sa.entry, sa.stack_top);
    
    SetObject (current, h, HANDLE_TYPE_PROCESS, proc);
    
    for (t=0; t < segment_cnt; t++)
    {
        PmapRemoveRegion (vs_ptrs[t]);
        vs_ptrs[t]->owner = proc;
    }
    
    proc->state = PROC_STATE_READY;
    SchedReady(proc);
    return h;
}
Ejemplo n.º 3
0
struct Process *CreateProcess (void (*entry)(void), void *stack, int policy, int priority, bits32_t flags, struct CPU *cpu)
{    
    int handle;
    struct Process *proc;
  
    
    proc = AllocProcess();
    handle = AllocHandle();

    KASSERT (handle >= 0);
        
    SetObject (proc, handle, HANDLE_TYPE_PROCESS, proc);
    
    proc->handle = handle;
    proc->exit_status = 0;
    
    proc->flags = flags;
    
   // FIXME: Move into AllocProcess ????????????????
    LIST_INIT (&proc->pending_handle_list);
    LIST_INIT (&proc->close_handle_list);
    
        
    PmapInit (proc);
    
    proc->task_state.cpu = cpu;
    proc->task_state.flags = 0;
    proc->task_state.pc = (uint32)entry;
    proc->task_state.r0 = 0;
    
    if (proc->flags & PROCF_DAEMON) {
        proc->task_state.cpsr = cpsr_dnm_state | SYS_MODE | CPSR_DEFAULT_BITS;
    }
    else {
        proc->task_state.cpsr = cpsr_dnm_state | USR_MODE | CPSR_DEFAULT_BITS;
    }
    
    proc->task_state.r1 = 0;
    proc->task_state.r2 = 0;
    proc->task_state.r3 = 0;
    proc->task_state.r4 = 0;
    proc->task_state.r5 = 0;
    proc->task_state.r6 = 0;
    proc->task_state.r7 = 0;
    proc->task_state.r8 = 0;
    proc->task_state.r9 = 0;
    proc->task_state.r10 = 0;
    proc->task_state.r11 = 0;
    proc->task_state.r12 = 0;
    proc->task_state.sp = (uint32)stack;
    proc->task_state.lr = 0;

    if (policy == SCHED_RR || policy == SCHED_FIFO)
    {
        proc->quanta_used = 0;
        proc->sched_policy = policy;
        proc->tickets = priority;
        SchedReady (proc);
    }
    else if (policy == SCHED_OTHER)
    {
        proc->quanta_used = 0;
        proc->sched_policy = policy;
        proc->tickets = priority;
        proc->stride = STRIDE1 / proc->tickets;
        proc->remaining = proc->stride;
        proc->pass = global_pass;
        SchedReady (proc);
    }
    else if (policy == SCHED_IDLE)
    {
        cpu->idle_process = proc;
    }


    return proc;
}