예제 #1
0
void acquire(struct w_spinlock* lk){

	// prevent deadlock
	push_cli();

	if(is_held(lk))
		return;
	
	//aquire the lock
	while(atomic_set(&lk->locked,1) != 0)
		;

	//set actual cpu that aquired the lock
	//lk->cpu = current_cpu
}
예제 #2
0
// get func worker
static uint16_t log_get_part( char *dest, uint16_t dest_sz, char **get_ptr_p )
{
    uint16_t len = 0;

    if( LOGBUF_DEBUG ) printf( "log_get_part( dest %p, sz %d, get_ptr_p %p (->%p) ), logbuf %p\n", dest, dest_sz, get_ptr_p, *get_ptr_p, logbuf );
    if( LOGBUF_DEBUG ) printf( "put_pos %p\n", put_pos );

    push_cli();


    if( *get_ptr_p == put_pos ) goto nothing;

    if( *get_ptr_p < put_pos )
    {
        len = put_pos - *get_ptr_p;
        if( len > dest_sz )
            len = dest_sz;

        memcpy( dest, *get_ptr_p, len );
    }
    else
    {
        len = place_to_end_of_buf( *get_ptr_p );

        if( len > dest_sz )
            len = dest_sz;

        memcpy( dest, *get_ptr_p, len );
    }

    *get_ptr_p += len;
    wrap_buf_ptr( get_ptr_p );

nothing:
    pop_sti();

    if( LOGBUF_DEBUG ) printf( "wrapped get_ptr_p -> %p ), get '%.*s'\n", *get_ptr_p, len, dest );

    return len;

}
예제 #3
0
// put func worker
static uint16_t log_put_part( const char *data, uint16_t len )
{
    push_cli();

    uint16_t place_left = place_to_end_of_buf(put_pos); //logbuf + LOG_MEM_SZ - put_pos;

    update_get_pos( &http_get_pos, len );
    update_get_pos( &syslog_get_pos, len );

    if( LOGBUF_DEBUG ) printf("log_put_part place_left=%d http_get_pos=%p logbuf=%p '%.*s'\n", place_left, http_get_pos, logbuf, len, data );

    if( len > place_left )
        len = place_left;

    memcpy( put_pos, data, len );

    put_pos += len;
    wrap_buf_ptr( &put_pos );

    pop_sti();

    return len;
}
예제 #4
0
파일: signal.c 프로젝트: jdetter/Chronos
int sig_handle(void)
{
	/* Make sure there is a signal being waited on. */
	if(!rproc->sig_queue)
		return 0;

	/* Not sure if interrupts will mess this up but better be sure */
	push_cli();

	/* Get the signal from the top of the queue */
	struct signal_t* sig = rproc->sig_queue;
	void (*sig_handler)(int sig_num) = 
		rproc->sigactions[sig->signum].sa_handler;
	int caught = 0; /* Did we catch the signal? */
	int terminated = 0; /* Did we get terminated? */
	int stopped = 0; /* Did we get stopped? */
	int core = 0; /* Should we dump the core? */
	int ignored = 0; /* Was the default action caught and ignored? */

	/* Does the user want us to use the default action? */
	if(rproc->sigactions[sig->signum].sa_handler == SIG_DFL)
		sig->catchable = 0; /* Make signal uncatchable */

	switch(rproc->sig_queue->default_action)
	{
		case SIGDEFAULT_KPANIC:
			panic("kernel: Invalid signal handled!\n");
			break;
		case SIGDEFAULT_TERM:
			if(sig->catchable)
			{
				caught = 1;
			} else {
				terminated = 1;
			}
			break;
		case SIGDEFAULT_CORE:
			if(sig->catchable)
			{
				caught = 1;
			} else { 
				core = terminated = 1;
			}
			break;
		case SIGDEFAULT_STOP:
			if(sig->catchable)
			{
				caught = 1;
			} else {
				stopped = 1;
			}
			break;
		case SIGDEFAULT_CONT:
			if(sig->catchable)
			{
				caught = 1;
			}
			break;
		case SIGDEFAULT_IGN:
			if(sig->catchable)
			{
				caught = 1;
			}
			break;
	}

	/** 
	 * If the user wants this signal to be ignored, ignore it. 
	 * EXCEPTIONS: if we are terminated, dumped or stopped then
	 * we must continue with the default action.
	 */
	if(rproc->sigactions[sig->signum].sa_handler == SIG_IGN)
	{
		if(!terminated && !stopped && !core)
			ignored = 1;
		caught = 0;
	}

	/* Were we able to catch the signal? */
	if(caught)
	{
		/* Do we have a signal stack? */
		if(!rproc->sig_stack_start)
		{
			/* TODO: probably don't use mmap here, this will */
			/*        change in the future.                  */

			/* Allocate a signal stack */
			int pages = SIG_DEFAULT_STACK + SIG_DEFAULT_GUARD;
			uint end = (uint)mmap(NULL, 
					pages * PGSIZE, 
					PROT_WRITE | PROT_READ,
					MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);

			/* Unmap all guard pages */
			int x;
			for(x = 0;x < SIG_DEFAULT_GUARD;x++)
			{
				vm_unmappage(end, rproc->pgdir);
				end += PGSIZE;
			}

			/* Set sig stack start */
			rproc->sig_stack_start = end + 
				(SIG_DEFAULT_STACK * PGSIZE);
		}

		/* Save the current trap frame if we need to */
		if(!rproc->sig_handling)
		{
			/* We weren't handling a signal until now */
			memmove(&rproc->sig_saved, 
					(char*)rproc->k_stack - sizeof(struct trap_frame),
					sizeof(struct trap_frame));
		}

		pstack_t stack = rproc->sig_stack_start;

		/* set the return address to the sig handler */
		rproc->tf->eip = (uintptr_t)sig_handler;

		vmflags_t dir_flags = VM_DIR_USRP | VM_DIR_READ | VM_DIR_WRIT;
		vmflags_t tbl_flags = VM_TBL_USRP | VM_TBL_READ | VM_TBL_WRIT;

		/* Push argument (sig) */
		stack -= sizeof(int);
		vm_memmove((void*)stack, &sig->signum, sizeof(int),
				rproc->pgdir, rproc->pgdir,
				dir_flags, tbl_flags);

		/* (safely) Push our magic return value */
		stack -= sizeof(int);
		uint32_t mag = SIG_MAGIC;
		vm_memmove((void*)stack, &mag, sizeof(int), 
				rproc->pgdir, rproc->pgdir,
				dir_flags, tbl_flags);

		/* Update stack pointer */
		rproc->tf->esp = stack;

		/* We are now actively handling this signal */
		rproc->sig_handling = 1;
	}

	pop_cli(); 

	/* Check to see if we need to dump the core */
	if(core)
	{
		/* Dump memory for gdb analysis */
#ifdef DEBUG
		cprintf("%s:%d: CORE DUMPED\n", rproc->name, rproc->pid);
#endif
		rproc->status_changed = 1;
		rproc->return_code = ((sig->signum & 0xFF) << 0x8) | 0x02;
		rproc->state = PROC_ZOMBIE;
		wake_parent(rproc);
		yield_withlock();
	}

	/* If we got stopped, we will enter scheduler. */
	if(stopped)
	{
#ifdef DEBUG
		cprintf("%s:%d: process stopped.\n", rproc->name, rproc->pid);
#endif

		rproc->status_changed = 1;
		rproc->state = PROC_STOPPED;
		rproc->return_code = ((sig->signum & 0xFF) << 0x08) | 0x04;
		/* Should we wake the parent? */
		if(!rproc->orphan && rproc->parent
				&& (rproc->parent->wait_options & WUNTRACED))
		{
			wake_parent(rproc);
		}
		sig_dequeue(rproc);
		yield_withlock();

		/* Should we wake our parent now that we've continued */
		rproc->status_changed = 1;
		if(!rproc->orphan && rproc->parent
				&& (rproc->parent->wait_options & WCONTINUED))
		{
			wake_parent(rproc);
		}

	}

	/* Check to see if we got terminated */
	if(terminated)
	{
#ifdef DEBUG
		cprintf("%s:%d: Process killed by signal. No core dumped.\n", 
				rproc->name, rproc->pid);
#endif

		rproc->status_changed = 1;
		rproc->return_code = ((sig->signum & 0xFF) << 0x08) | 0x01;
		rproc->state = PROC_ZOMBIE;
		wake_parent(rproc);
		yield_withlock();
	}

	if(ignored)
		sig_dequeue(rproc);

	return 0;
}