void ring_buffer_destroy(ring_buffer_t * ring_buffer) { free(ring_buffer->buffer); wakeup_queue(ring_buffer->wait_queue_writers); wakeup_queue(ring_buffer->wait_queue_readers); list_free(ring_buffer->wait_queue_writers); list_free(ring_buffer->wait_queue_readers); free(ring_buffer->wait_queue_writers); free(ring_buffer->wait_queue_readers); }
uint32_t write_pipe(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) { assert(node->device != 0 && "Attempted to write to a fully-closed pipe."); /* Retreive the pipe object associated with this file node */ pipe_device_t * pipe = (pipe_device_t *)node->device; #if DEBUG_PIPES if (pipe->size > 300) { /* Ignore small pipes (ie, keyboard) */ debug_print(INFO, "[debug] Call to write to pipe 0x%x", node->device); debug_print(INFO, " Available space: %d", pipe_available(pipe)); debug_print(INFO, " Total size: %d", pipe->size); debug_print(INFO, " Request size: %d", size); debug_print(INFO, " Write pointer: %d", pipe->write_ptr); debug_print(INFO, " Read pointer: %d", pipe->read_ptr); debug_print(INFO, " Buffer address: 0x%x", pipe->buffer); debug_print(INFO, " Write: %s", buffer); } #endif if (pipe->dead) { debug_print(WARNING, "Pipe is dead?"); send_signal(getpid(), SIGPIPE); return 0; } size_t written = 0; while (written < size) { spin_lock(pipe->lock_write); #if 0 size_t available = 0; if (pipe->read_ptr <= pipe->write_ptr) { available = pipe->size - pipe->write_ptr; } else { available = pipe->read_ptr - pipe->write_ptr - 1; } if (available) { available = min(available, size - written); memcpy(&pipe->buffer[pipe->write_ptr], buffer, available); pipe_increment_write_by(pipe, available); written += available; } #else while (pipe_available(pipe) > 0 && written < size) { pipe->buffer[pipe->write_ptr] = buffer[written]; pipe_increment_write(pipe); written++; } #endif spin_unlock(pipe->lock_write); wakeup_queue(pipe->wait_queue_readers); pipe_alert_waiters(pipe); if (written < size) { sleep_on(pipe->wait_queue_writers); } } return written; }
static int rtl_irq_handler(struct regs *r) { uint16_t status = inports(rtl_iobase + RTL_PORT_ISR); if (!status) { return 0; } outports(rtl_iobase + RTL_PORT_ISR, status); irq_ack(rtl_irq); if (status & 0x01 || status & 0x02) { /* Receive */ while((inportb(rtl_iobase + RTL_PORT_CMD) & 0x01) == 0) { int offset = cur_rx % 0x2000; #if 0 uint16_t buf_addr = inports(rtl_iobase + RTL_PORT_RXADDR); uint16_t buf_ptr = inports(rtl_iobase + RTL_PORT_RXPTR); uint8_t cmd = inportb(rtl_iobase + RTL_PORT_CMD); #endif uint32_t * buf_start = (uint32_t *)((uintptr_t)rtl_rx_buffer + offset); uint32_t rx_status = buf_start[0]; int rx_size = rx_status >> 16; if (rx_status & (0x0020 | 0x0010 | 0x0004 | 0x0002)) { debug_print(WARNING, "rx error :("); } else { uint8_t * buf_8 = (uint8_t *)&(buf_start[1]); last_packet = malloc(rx_size); uintptr_t packet_end = (uintptr_t)buf_8 + rx_size; if (packet_end > (uintptr_t)rtl_rx_buffer + 0x2000) { size_t s = ((uintptr_t)rtl_rx_buffer + 0x2000) - (uintptr_t)buf_8; memcpy(last_packet, buf_8, s); memcpy((void *)((uintptr_t)last_packet + s), rtl_rx_buffer, rx_size - s); } else { memcpy(last_packet, buf_8, rx_size); } rtl_enqueue(last_packet); } cur_rx = (cur_rx + rx_size + 4 + 3) & ~3; outports(rtl_iobase + RTL_PORT_RXPTR, cur_rx - 16); } wakeup_queue(rx_wait); } if (status & 0x08 || status & 0x04) { unsigned int i = inportl(rtl_iobase + RTL_PORT_TXSTAT + 4 * dirty_tx); (void)i; dirty_tx++; if (dirty_tx == 5) dirty_tx = 0; } return 1; }
static void kswapd_wakeup_all(void) { bool intr_flag; local_intr_save(intr_flag); { wakeup_queue(&kswapd_done, WT_KSWAPD, 1); } local_intr_restore(intr_flag); }
size_t ring_buffer_read(ring_buffer_t * ring_buffer, size_t size, uint8_t * buffer) { size_t collected = 0; while (collected == 0) { spin_lock(ring_buffer->lock); while (ring_buffer_unread(ring_buffer) > 0 && collected < size) { buffer[collected] = ring_buffer->buffer[ring_buffer->read_ptr]; ring_buffer_increment_read(ring_buffer); collected++; } spin_unlock(ring_buffer->lock); wakeup_queue(ring_buffer->wait_queue_writers); if (collected == 0) { if (sleep_on(ring_buffer->wait_queue_readers) && ring_buffer->internal_stop) { ring_buffer->internal_stop = 0; break; } } } wakeup_queue(ring_buffer->wait_queue_writers); return collected; }
int ipu_put_data(struct vpu_display *disp, int index, int field, int fps) { /*TODO: ipu lib dose not support fps control yet*/ disp->ipu_bufs[index].field = field; if (field == V4L2_FIELD_TOP || field == V4L2_FIELD_BOTTOM || field == V4L2_FIELD_INTERLACED_TB || field == V4L2_FIELD_INTERLACED_BT) disp->deinterlaced = 1; queue_buf(&(disp->ipu_q), index); wakeup_queue(); return 0; }
size_t ring_buffer_write(ring_buffer_t * ring_buffer, size_t size, uint8_t * buffer) { size_t written = 0; while (written < size) { spin_lock(ring_buffer->lock); while (ring_buffer_available(ring_buffer) > 0 && written < size) { ring_buffer->buffer[ring_buffer->write_ptr] = buffer[written]; ring_buffer_increment_write(ring_buffer); written++; } spin_unlock(ring_buffer->lock); wakeup_queue(ring_buffer->wait_queue_readers); if (written < size) { if (sleep_on(ring_buffer->wait_queue_writers) && ring_buffer->internal_stop) { ring_buffer->internal_stop = 0; break; } } } wakeup_queue(ring_buffer->wait_queue_readers); return written; }
void dev_stdin_write(char c) { bool intr_flag; if (c != '\0') { local_intr_save(intr_flag); { stdin_buffer[p_wpos % STDIN_BUFSIZE] = c; if (p_wpos - p_rpos < STDIN_BUFSIZE) { p_wpos ++; } if (!wait_queue_empty(wait_queue)) { wakeup_queue(wait_queue, WT_KBD, 1); } } local_intr_restore(intr_flag); } }
uint32_t read_pipe(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) { assert(node->device != 0 && "Attempted to read from a fully-closed pipe."); /* Retreive the pipe object associated with this file node */ pipe_device_t * pipe = (pipe_device_t *)node->device; #if DEBUG_PIPES if (pipe->size > 300) { /* Ignore small pipes (ie, keyboard) */ debug_print(INFO, "[debug] Call to read from pipe 0x%x", node->device); debug_print(INFO, " Unread bytes: %d", pipe_unread(pipe)); debug_print(INFO, " Total size: %d", pipe->size); debug_print(INFO, " Request size: %d", size); debug_print(INFO, " Write pointer: %d", pipe->write_ptr); debug_print(INFO, " Read pointer: %d", pipe->read_ptr); debug_print(INFO, " Buffer address: 0x%x", pipe->buffer); } #endif if (pipe->dead) { debug_print(WARNING, "Pipe is dead?"); send_signal(getpid(), SIGPIPE); return 0; } size_t collected = 0; while (collected == 0) { spin_lock(pipe->lock_read); while (pipe_unread(pipe) > 0 && collected < size) { buffer[collected] = pipe->buffer[pipe->read_ptr]; pipe_increment_read(pipe); collected++; } spin_unlock(pipe->lock_read); wakeup_queue(pipe->wait_queue_writers); /* Deschedule and switch */ if (collected == 0) { sleep_on(pipe->wait_queue_readers); } } return collected; }
void ipu_display_close(struct vpu_display *disp) { int i; disp->stopping = 1; disp->deinterlaced = 0; while(ipu_running && ((queue_size(&(disp->ipu_q)) > 0) || !ipu_waiting)) usleep(10000); if (ipu_running) { wakeup_queue(); info_msg("Join disp loop thread\n"); pthread_join(disp->ipu_disp_loop_thread, NULL); } pthread_mutex_destroy(&ipu_mutex); pthread_cond_destroy(&ipu_cond); for (i=0;i<disp->nframes;i++) ipu_memory_free(disp->frame_size, 1, &(disp->ipu_bufs[i].ipu_paddr), &(disp->ipu_bufs[i].ipu_vaddr), disp->fd); close(disp->fd); free(disp); }
int ipc_sem_free(sem_t sem_id) { assert(current->sem_queue != NULL); sem_undo_t *semu; sem_queue_t *sem_queue = current->sem_queue; down(&(sem_queue->sem)); semu = semu_list_search(&(sem_queue->semu_list), sem_id); up(&(sem_queue->sem)); int ret = -E_INVAL; if (semu != NULL) { bool intr_flag; local_intr_save(intr_flag); { semaphore_t *sem = semu->sem; sem->valid = 0, ret = 0; wakeup_queue(&(sem->wait_queue), WT_INTERRUPTED, 1); } local_intr_restore(intr_flag); } return ret; }
// __do_exit - cause a thread exit (use do_exit, do_exit_thread instead) // 1. call exit_mmap & put_pgdir & mm_destroy to free the almost all memory space of process // 2. set process' state as PROC_ZOMBIE, then call wakeup_proc(parent) to ask parent reclaim itself. // 3. call scheduler to switch to other process static int __do_exit(void) { if (current == idleproc) { panic("idleproc exit.\n"); } if (current == initproc) { panic("initproc exit.\n"); } struct mm_struct *mm = current->mm; if (mm != NULL) { mm->lapic = -1; mp_set_mm_pagetable(NULL); if (mm_count_dec(mm) == 0) { exit_mmap(mm); put_pgdir(mm); bool intr_flag; local_intr_save(intr_flag); { list_del(&(mm->proc_mm_link)); } local_intr_restore(intr_flag); mm_destroy(mm); } current->mm = NULL; } put_sighand(current); put_signal(current); put_fs(current); put_sem_queue(current); current->state = PROC_ZOMBIE; bool intr_flag; struct proc_struct *proc, *parent; local_intr_save(intr_flag); { proc = parent = current->parent; do { if (proc->wait_state == WT_CHILD) { wakeup_proc(proc); } proc = next_thread(proc); } while (proc != parent); if ((parent = next_thread(current)) == current) { parent = initproc; } de_thread(current); while (current->cptr != NULL) { proc = current->cptr; current->cptr = proc->optr; proc->yptr = NULL; if ((proc->optr = parent->cptr) != NULL) { parent->cptr->yptr = proc; } proc->parent = parent; parent->cptr = proc; if (proc->state == PROC_ZOMBIE) { if (parent->wait_state == WT_CHILD) { wakeup_proc(parent); } } } } wakeup_queue(&(current->event_box.wait_queue), WT_INTERRUPTED, 1); local_intr_restore(intr_flag); schedule(); panic("__do_exit will not return!! %d %d.\n", current->pid, current->exit_code); }
void sema_up(sema_t *sema) { sema->ctr++; /* wake up threads that are waiting */ wakeup_queue(&sema->wait_list); }