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 }
// 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; }
// 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; }
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; }