Пример #1
0
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);
}
Пример #2
0
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;
}
Пример #3
0
Файл: rtl.c Проект: Saruta/ToyOS
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;
}
Пример #4
0
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);
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
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;
}
Пример #8
0
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);
    }
}
Пример #9
0
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;
}
Пример #10
0
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);
}
Пример #11
0
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;
}
Пример #12
0
// __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);
}
Пример #13
0
void sema_up(sema_t *sema)
{
    sema->ctr++;
    /* wake up threads that are waiting */
    wakeup_queue(&sema->wait_list);
}