feat: simple wait queue implementation for efficient waiting.
fix: dead lock when invoking sched_yieldk() inside interrupt context.
chore: refactorings and clean up.
#include <lunaix/ds/hstr.h>
#include <lunaix/ds/llist.h>
+#include <lunaix/types.h>
#define DEV_MSKIF 0x00000003
int (*write)(struct device* dev, void* buf, size_t offset, size_t len);
};
+struct device*
+device_add(struct device* parent,
+ void* underlay,
+ char* name_fmt,
+ uint32_t type,
+ va_list args);
+
struct device*
device_addseq(struct device* parent, void* underlay, char* name_fmt, ...);
device_getbyid(struct llist_header* devlist, dev_t id);
struct device*
-device_getbyname(struct llist_header* devlist, struct hstr* name);
+device_getbyhname(struct llist_header* devlist, struct hstr* name);
+
+struct device*
+device_getbyname(struct llist_header* devlist, const char* name, size_t len);
struct device*
device_getbyoffset(struct llist_header* devlist, int pos);
--- /dev/null
+#ifndef __LUNAIX_CODVAR_H
+#define __LUNAIX_CODVAR_H
+
+#include <lunaix/ds/llist.h>
+
+typedef struct waitq
+{
+ struct llist_header waiters;
+} waitq_t;
+
+inline void
+waitq_init(waitq_t* waitq)
+{
+ llist_init_head(&waitq->waiters);
+}
+
+void
+pwait(waitq_t* queue);
+
+void
+pwake_one(waitq_t* queue);
+
+void
+pwake_all(waitq_t* queue);
+
+#endif /* __LUNAIX_CODVAR_H */
--- /dev/null
+#ifndef __LUNAIX_INPUT_H
+#define __LUNAIX_INPUT_H
+
+#include <lunaix/clock.h>
+#include <lunaix/device.h>
+#include <lunaix/ds/llist.h>
+#include <lunaix/ds/waitq.h>
+#include <lunaix/types.h>
+
+// event should propagate further
+#define INPUT_EVT_NEXT 0
+// event should be captured here
+#define INPUT_EVT_CATCH 1
+
+// key pressed (key-type device)
+#define PKT_PRESS 0x1
+// key released (key-type device)
+#define PKT_RELEASE 0x2
+// vector (e.g. mice wheel scroll, mice maneuver)
+#define PKT_VECTOR 0x3
+
+struct input_evt_pkt
+{
+ uint32_t pkt_type; // packet type
+ uint32_t scan_code; // hardware raw code
+ uint32_t sys_code; // driver translated code
+ time_t timestamp; // event timestamp
+};
+
+struct input_device
+{
+ struct device* dev_if; // device interface
+ struct input_evt_pkt current_pkt; // recieved event packet
+ waitq_t readers; // reader wait queue
+};
+
+typedef int (*input_evt_cb)(struct input_device* dev);
+
+struct input_evt_chain
+{
+ struct llist_header chain;
+ input_evt_cb evt_cb;
+};
+
+void
+input_init();
+
+void
+input_fire_event(struct input_device* idev, struct input_evt_pkt* pkt);
+
+void
+input_add_listener(input_evt_cb listener);
+
+struct input_device*
+input_add_device(char* name_fmt, ...);
+
+#endif /* __LUNAIX_INPUT_H */
typedef unsigned short kbd_keycode_t;
typedef unsigned short kbd_kstate_t;
-#define KEYPAD 0x0100
-#define FN_KEY 0x0200
-#define CURSOR 0x0300
-#define MODIFR 0x0400
-#define OTHERS 0xff00
+#define KEYPAD 0x0100
+#define FN_KEY 0x0200
+#define CURSOR 0x0300
+#define MODIFR 0x0400
+#define OTHERS 0xff00
-#define ON_KEYPAD(x) ((x & 0xff) | KEYPAD)
+#define ON_KEYPAD(x) ((x & 0xff) | KEYPAD)
// backspace key
-#define KEY_BS (0x08)
+#define KEY_BS (0x08)
// enter/return key
-#define KEY_LF (0x0a)
+#define KEY_LF (0x0a)
#define KEY_HTAB (0x9)
#define KEY_SPACE (0x20)
#define KEY_ESC (0x1b)
-#define KEY_F1 (0x00 | FN_KEY)
-#define KEY_F2 (0x01 | FN_KEY)
-#define KEY_F3 (0x02 | FN_KEY)
-#define KEY_F4 (0x03 | FN_KEY)
-#define KEY_F5 (0x04 | FN_KEY)
-#define KEY_F6 (0x05 | FN_KEY)
-#define KEY_F7 (0x06 | FN_KEY)
-#define KEY_F8 (0x07 | FN_KEY)
-#define KEY_F9 (0x08 | FN_KEY)
+#define KEY_F1 (0x00 | FN_KEY)
+#define KEY_F2 (0x01 | FN_KEY)
+#define KEY_F3 (0x02 | FN_KEY)
+#define KEY_F4 (0x03 | FN_KEY)
+#define KEY_F5 (0x04 | FN_KEY)
+#define KEY_F6 (0x05 | FN_KEY)
+#define KEY_F7 (0x06 | FN_KEY)
+#define KEY_F8 (0x07 | FN_KEY)
+#define KEY_F9 (0x08 | FN_KEY)
#define KEY_F10 (0x09 | FN_KEY)
#define KEY_F11 (0x0a | FN_KEY)
#define KEY_F12 (0x0b | FN_KEY)
#define KEY_NUMSLK (0x0d | FN_KEY)
#define KEY_SCRLLK (0x0e | FN_KEY)
-#define KEY_PG_UP (0x0 | OTHERS)
-#define KEY_PG_DOWN (0x1 | OTHERS)
-#define KEY_INSERT (0x2 | OTHERS)
-#define KEY_DELETE (0x3 | OTHERS)
-#define KEY_HOME (0x4 | OTHERS)
-#define KEY_END (0x5 | OTHERS)
-#define KEY_PAUSE (0x6 | OTHERS)
-
-#define KEY_LEFT (0x0 | CURSOR)
-#define KEY_RIGHT (0x1 | CURSOR)
-#define KEY_UP (0x2 | CURSOR)
-#define KEY_DOWN (0x3 | CURSOR)
-
-#define KEY_LSHIFT (0x0 | MODIFR)
-#define KEY_RSHIFT (0x1 | MODIFR)
-#define KEY_LCTRL (0x2 | MODIFR)
-#define KEY_RCTRL (0x3 | MODIFR)
-#define KEY_LALT (0x4 | MODIFR)
-#define KEY_RALT (0x5 | MODIFR)
+#define KEY_PG_UP (0x0 | OTHERS)
+#define KEY_PG_DOWN (0x1 | OTHERS)
+#define KEY_INSERT (0x2 | OTHERS)
+#define KEY_DELETE (0x3 | OTHERS)
+#define KEY_HOME (0x4 | OTHERS)
+#define KEY_END (0x5 | OTHERS)
+#define KEY_PAUSE (0x6 | OTHERS)
+
+#define KEY_LEFT (0x0 | CURSOR)
+#define KEY_RIGHT (0x1 | CURSOR)
+#define KEY_UP (0x2 | CURSOR)
+#define KEY_DOWN (0x3 | CURSOR)
+
+#define KEY_LSHIFT (0x0 | MODIFR)
+#define KEY_RSHIFT (0x1 | MODIFR)
+#define KEY_LCTRL (0x2 | MODIFR)
+#define KEY_RCTRL (0x3 | MODIFR)
+#define KEY_LALT (0x4 | MODIFR)
+#define KEY_RALT (0x5 | MODIFR)
#define KBD_KEY_FRELEASED 0x0
#define KBD_KEY_FPRESSED 0x1
#define KBD_KEY_FLALT_HELD 0x100
#define KBD_KEY_FRALT_HELD 0x200
-typedef unsigned char kbd_scancode_t;
-
-struct kdb_keyinfo_pkt {
- kbd_scancode_t scancode;
- kbd_keycode_t keycode;
- kbd_kstate_t state;
- time_t timestamp;
-};
-
-int kbd_recv_key(struct kdb_keyinfo_pkt* key_event);
-
#endif /* __LUNAIX_KEYBOARD_H */
#define PS2_DELAY 1000
#define PS2_CMD_QUEUE_SIZE 8
-#define PS2_KBD_RECV_BUFFER_SIZE 8
#define PS2_NO_ARG 0xff00
mutex_t mutex;
};
-struct ps2_key_buffer
-{
- struct kdb_keyinfo_pkt buffer[PS2_KBD_RECV_BUFFER_SIZE];
- int read_ptr;
- int buffered_len;
- mutex_t mutex;
-};
-
/**
* @brief 向PS/2控制器的控制端口(0x64)发送指令并等待返回代码。
* 注意,对于没有返回代码的命令请使用`ps2_post_cmd`,否则会造成死锁。
#include <arch/x86/interrupts.h>
#include <lunaix/clock.h>
+#include <lunaix/ds/waitq.h>
#include <lunaix/fs.h>
#include <lunaix/mm/mm.h>
#include <lunaix/signal.h>
// 虽然内核不是进程,但为了区分,这里使用Pid=-1来指代内核。这主要是方便物理页所有权检查。
#define KERNEL_PID -1
-#define PS_STOPPED 0
+#define PS_READY 0
#define PS_RUNNING 1
#define PS_TERMNAT 2
#define PS_DESTROY 4
struct llist_header siblings;
struct llist_header children;
struct llist_header grp_member;
+ waitq_t waitqueue;
struct
{
#ifndef __LUNAIX_TYPES_H
#define __LUNAIX_TYPES_H
+#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
--- /dev/null
+#include <lunaix/fctrl.h>
+#include <lunaix/foptions.h>
+#include <lunaix/input.h>
+#include <lunaix/lunistd.h>
+
+#define STDIN 1
+#define STDOUT 0
+
+void
+input_test()
+{
+ int fd = open("/dev/input/i8042-kbd", 0);
+
+ if (fd < 0) {
+ write(STDOUT, "fail to open", 13);
+ return;
+ }
+
+ struct input_evt_pkt event;
+
+ while (read(fd, &event, sizeof(event)) > 0) {
+ if (event.pkt_type == PKT_PRESS) {
+ write(STDOUT, "PRESSED: ", 10);
+ } else {
+ write(STDOUT, "RELEASE: ", 10);
+ }
+ char c = event.sys_code & 0xff;
+ write(STDOUT, &c, 1);
+ write(STDOUT, "\n", 2);
+ }
+ return;
+}
\ No newline at end of file
int
devfs_dirlookup(struct v_inode* this, struct v_dnode* dnode)
{
- struct device* dev = device_getbyname(this->data, &dnode->name);
+ struct device* dev = device_getbyhname(this->data, &dnode->name);
if (!dev) {
return ENOENT;
}
static volatile dev_t devid = 0;
struct device*
-__device_add(struct device* parent,
- void* underlay,
- char* name_fmt,
- uint32_t type,
- va_list args)
+device_add(struct device* parent,
+ void* underlay,
+ char* name_fmt,
+ uint32_t type,
+ va_list args)
{
struct device* dev = vzalloc(sizeof(struct device));
va_start(args, name_fmt);
struct device* dev =
- __device_add(parent, underlay, name_fmt, DEV_IFSEQ, args);
+ device_add(parent, underlay, name_fmt, DEV_IFSEQ, args);
va_end(args);
return dev;
va_start(args, name_fmt);
struct device* dev =
- __device_add(parent, underlay, name_fmt, DEV_IFVOL, args);
+ device_add(parent, underlay, name_fmt, DEV_IFVOL, args);
va_end(args);
return dev;
va_list args;
va_start(args, name_fmt);
- struct device* dev = __device_add(parent, NULL, name_fmt, DEV_IFCAT, args);
+ struct device* dev = device_add(parent, NULL, name_fmt, DEV_IFCAT, args);
va_end(args);
return dev;
}
struct device*
-device_getbyname(struct llist_header* devlist, struct hstr* name)
+device_getbyhname(struct llist_header* devlist, struct hstr* name)
{
devlist = devlist ? devlist : &root_list;
struct device *pos, *n;
return NULL;
}
+struct device*
+device_getbyname(struct llist_header* devlist, const char* name, size_t len)
+{
+ struct hstr hname = HSTR(name, len);
+ hstr_rehash(&hname, HSTR_FULL_HASH);
+
+ return device_getbyhname(devlist, &hname);
+}
+
void
device_remove(struct device* dev)
{
--- /dev/null
+#include <lunaix/clock.h>
+#include <lunaix/input.h>
+#include <lunaix/mm/valloc.h>
+#include <lunaix/spike.h>
+#include <lunaix/status.h>
+
+#include <klibc/string.h>
+
+static DEFINE_LLIST(listener_chain);
+
+static struct device* input_devcat = NULL;
+
+void
+input_init()
+{
+ input_devcat = device_addcat(NULL, "input");
+}
+
+void
+input_fire_event(struct input_device* idev, struct input_evt_pkt* pkt)
+{
+ pkt->timestamp = clock_systime();
+ idev->current_pkt = *pkt;
+
+ struct input_evt_chain *pos, *n;
+ llist_for_each(pos, n, &listener_chain, chain)
+ {
+ if (pos->evt_cb(idev) == INPUT_EVT_CATCH) {
+ break;
+ }
+ }
+
+ // wake up all pending readers
+ pwake_all(&idev->readers);
+}
+
+void
+input_add_listener(input_evt_cb listener)
+{
+ assert(listener);
+
+ struct input_evt_chain* chain = vzalloc(sizeof(*chain));
+ llist_append(&listener_chain, &chain->chain);
+
+ chain->evt_cb = listener;
+}
+
+int
+__input_dev_read(struct device* dev, void* buf, size_t offset, size_t len)
+{
+ struct input_device* idev = dev->underlay;
+
+ if (len < sizeof(struct input_evt_pkt)) {
+ return ERANGE;
+ }
+
+ // wait for new event
+ pwait(&idev->readers);
+
+ memcpy(buf, &idev->current_pkt, sizeof(struct input_evt_pkt));
+
+ return sizeof(struct input_evt_pkt);
+}
+
+struct input_device*
+input_add_device(char* name_fmt, ...)
+{
+ assert(input_devcat);
+
+ struct input_device* idev = vzalloc(sizeof(*idev));
+ waitq_init(&idev->readers);
+
+ va_list args;
+ va_start(args, name_fmt);
+
+ struct device* dev =
+ device_add(input_devcat, idev, name_fmt, DEV_IFSEQ, args);
+
+ idev->dev_if = dev;
+ dev->read = __input_dev_read;
+
+ va_end(args);
+
+ return idev;
+}
--- /dev/null
+#include <lunaix/ds/waitq.h>
+#include <lunaix/process.h>
+#include <lunaix/sched.h>
+#include <lunaix/spike.h>
+
+void
+pwait(waitq_t* queue)
+{
+ waitq_t* current_wq = &__current->waitqueue;
+ assert(llist_empty(¤t_wq->waiters));
+
+ llist_append(&queue->waiters, ¤t_wq->waiters);
+
+ // FIXME centralize the state change.
+ __current->state = PS_BLOCKED;
+ sched_yieldk();
+}
+
+void
+pwake_one(waitq_t* queue)
+{
+ if (llist_empty(&queue->waiters)) {
+ return;
+ }
+
+ waitq_t* wq = list_entry(queue->waiters.next, waitq_t, waiters);
+ struct proc_info* proc = container_of(wq, struct proc_info, waitqueue);
+
+ assert(proc->state == PS_BLOCKED);
+ proc->state = PS_READY;
+ llist_delete(&wq->waiters);
+}
+
+void
+pwake_all(waitq_t* queue)
+{
+ if (llist_empty(&queue->waiters)) {
+ return;
+ }
+
+ struct proc_info* proc;
+ waitq_t *pos, *n;
+ llist_for_each(pos, n, &queue->waiters, waiters)
+ {
+ proc = container_of(pos, struct proc_info, waitqueue);
+
+ proc->state = PS_READY;
+ llist_delete(&pos->waiters);
+ }
+}
\ No newline at end of file
#include <lunaix/device.h>
#include <lunaix/foptions.h>
+#include <lunaix/input.h>
#include <lunaix/lxconsole.h>
#include <lunaix/mm/page.h>
#include <lunaix/mm/pmm.h>
cake_init();
valloc_init();
- lxconsole_init();
-
vfs_init();
fsm_init();
+ input_init();
if ((errno = vfs_mount_root("ramfs", NULL))) {
panickf("Fail to mount root. (errno=%d)", errno);
vfs_mount("/dev", "devfs", NULL, 0);
vfs_mount("/sys", "twifs", NULL, MNT_RO);
+ lxconsole_init();
+
sched_init();
spawn_proc0();
#include <klibc/string.h>
#include <lunaix/device.h>
+#include <lunaix/input.h>
#include <lunaix/keyboard.h>
#include <lunaix/lxconsole.h>
#include <lunaix/mm/pmm.h>
int
__tty_read(struct device* dev, void* buf, size_t offset, size_t len);
+static waitq_t lx_reader;
+static volatile char key;
+
+int
+__lxconsole_listener(struct input_device* dev)
+{
+ uint32_t keycode = dev->current_pkt.sys_code;
+ uint32_t type = dev->current_pkt.pkt_type;
+ if (type == PKT_PRESS) {
+ if (keycode == KEY_UP) {
+ console_view_up();
+ } else if (keycode == KEY_DOWN) {
+ console_view_down();
+ }
+ goto done;
+ }
+ if ((keycode & 0xff00) > KEYPAD) {
+ goto done;
+ }
+
+ key = (char)(keycode & 0x00ff);
+
+ pwake_all(&lx_reader);
+
+done:
+ return INPUT_EVT_NEXT;
+}
+
void
lxconsole_init()
{
struct device* tty_dev = device_addseq(NULL, &lx_console, "tty");
tty_dev->write = __tty_write;
tty_dev->read = __tty_read;
+
+ waitq_init(&lx_reader);
+ input_add_listener(__lxconsole_listener);
}
int
int
__tty_read(struct device* dev, void* buf, size_t offset, size_t len)
{
- struct kdb_keyinfo_pkt keyevent;
struct console* console = (struct console*)dev->underlay;
size_t count = fifo_read(&console->input, buf, len);
}
while (count < len) {
- // FIXME RACE!
- // Consider two process that is polling the input key simultaneously.
- // When a key is arrived, one of the processes will win the race and
- // swallow it (advancing the key buffer pointer)
- if (!kbd_recv_key(&keyevent)) {
- sched_yieldk();
- continue;
- }
- if (!(keyevent.state & KBD_KEY_FPRESSED)) {
- continue;
- }
- if ((keyevent.keycode & 0xff00) > KEYPAD) {
- continue;
- }
+ pwait(&lx_reader);
- char c = (char)(keyevent.keycode & 0x00ff);
- if (c == 0x08) {
+ if (key == 0x08) {
if (fifo_backone(&console->input)) {
- console_write_char(c);
+ console_write_char(key);
}
continue;
}
- console_write_char(c);
- if (!fifo_putone(&console->input, c) || c == '\n') {
+ console_write_char(key);
+ if (!fifo_putone(&console->input, key) || key == '\n') {
break;
}
}
#include <hal/ioapic.h>
#include <lunaix/clock.h>
#include <lunaix/common.h>
+#include <lunaix/input.h>
#include <lunaix/peripheral/ps2kbd.h>
#include <lunaix/syslog.h>
#include <lunaix/timer.h>
LOG_MODULE("PS2KBD");
static struct ps2_cmd_queue cmd_q;
-static struct ps2_key_buffer key_buf;
static struct ps2_kbd_state kbd_state;
#define KEY_NUM(x) (x + 0x30)
// clang-format on
+static struct input_device* kbd_idev;
+
#define KBD_STATE_KWAIT 0x00
#define KBD_STATE_KSPECIAL 0x01
#define KBD_STATE_KRELEASED 0x02
void
intr_ps2_kbd_handler(const isr_param* param);
-static struct kdb_keyinfo_pkt*
-ps2_keybuffer_next_write();
void
ps2_device_post_cmd(char cmd, char arg)
{
memset(&cmd_q, 0, sizeof(cmd_q));
- memset(&key_buf, 0, sizeof(key_buf));
memset(&kbd_state, 0, sizeof(kbd_state));
mutex_init(&cmd_q.mutex);
- mutex_init(&key_buf.mutex);
kbd_state.translation_table = scancode_set2;
kbd_state.state = KBD_STATE_KWAIT;
+ kbd_idev = input_add_device("i8042-kbd");
+
acpi_context* acpi_ctx = acpi_get_context();
if (acpi_ctx->fadt.header.rev > 1) {
/*
* https://bochs.sourceforge.io/cgi-bin/lxr/source/bios/rombios32.c#L1314
*/
if (!(acpi_ctx->fadt.boot_arch & IAPC_ARCH_8042)) {
- kprintf(KERROR "No PS/2 controller detected.\n");
+ kprintf(KERROR "i8042: not found\n");
// FUTURE: Some alternative fallback on this? Check PCI bus for USB
// controller instead?
return;
}
} else {
- kprintf(KWARN "Outdated FADT used, assuming 8042 always exist.\n");
+ kprintf(KWARN "i8042: outdated FADT used, assuming exists.\n");
}
char result;
key = key & (0xffdf |
-('a' > key || key > 'z' || !(state & KBD_KEY_FCAPSLKED)));
- if (!mutex_on_hold(&key_buf.mutex)) {
- struct kdb_keyinfo_pkt* keyevent_pkt = ps2_keybuffer_next_write();
- *keyevent_pkt =
- (struct kdb_keyinfo_pkt){ .keycode = key,
- .scancode = scancode,
- .state = state,
- .timestamp = clock_systime() };
- }
+ struct input_evt_pkt ipkt = {
+ .pkt_type = (state & KBD_KEY_FPRESSED) ? PKT_PRESS : PKT_RELEASE,
+ .scan_code = scancode,
+ .sys_code = key,
+ };
+
+ input_fire_event(kbd_idev, &ipkt);
return;
}
;
return io_inb(PS2_PORT_ENC_CMDREG);
-}
-
-int
-kbd_recv_key(struct kdb_keyinfo_pkt* key_event)
-{
- if (!key_buf.buffered_len) {
- return 0;
- }
-
- mutex_lock(&key_buf.mutex);
- *key_event = key_buf.buffer[key_buf.read_ptr];
- key_buf.buffered_len--;
- key_buf.read_ptr = (key_buf.read_ptr + 1) % PS2_KBD_RECV_BUFFER_SIZE;
-
- mutex_unlock(&key_buf.mutex);
- return 1;
-}
-
-static struct kdb_keyinfo_pkt*
-ps2_keybuffer_next_write()
-{
- int index =
- (key_buf.read_ptr + key_buf.buffered_len) % PS2_KBD_RECV_BUFFER_SIZE;
- if (index == key_buf.read_ptr && key_buf.buffered_len) {
- // the reader is lagged so much such that the buffer is full.
- // It is suggested to read from beginning for nearly up-to-date
- // readings.
- key_buf.read_ptr = 0;
- key_buf.buffered_len = index;
- } else {
- key_buf.buffered_len++;
- }
- return &key_buf.buffer[index];
}
\ No newline at end of file
#define USE_DEMO
// #define DEMO_SIGNAL
-//#define DEMO_READDIR
-#define DEMO_IOTEST
+// #define DEMO_READDIR
+// #define DEMO_IOTEST
+#define DEMO_INPUT_TEST
extern void
_pconsole_main();
extern void
_iotest_main();
+extern void
+input_test();
+
void __USER__
__proc0_usr()
{
int stdin = dup2(stdout, 1);
pid_t p;
- if (!fork()) {
- _pconsole_main();
- }
+ // if (!fork()) {
+ // _pconsole_main();
+ // }
if (!(p = fork())) {
#ifndef USE_DEMO
_readdir_main();
#elif defined DEMO_IOTEST
_iotest_main();
+#elif defined DEMO_INPUT_TEST
+ input_test();
#else
_lxinit_main();
#endif
if (wtime && now >= wtime) {
pos->sleep.wakeup_time = 0;
- pos->state = PS_STOPPED;
+ pos->state = PS_READY;
}
if (atime && now >= atime) {
int ptr = prev_ptr;
if (!(__current->state & ~PS_RUNNING)) {
- __current->state = PS_STOPPED;
+ __current->state = PS_READY;
}
check_sleepers();
do {
ptr = (ptr + 1) % sched_ctx.ptable_len;
next = &sched_ctx._procs[ptr];
- } while (next->state != PS_STOPPED && ptr != prev_ptr);
+ } while (next->state != PS_READY && ptr != prev_ptr);
sched_ctx.procs_index = ptr;
void
sched_yieldk()
{
+ cpu_enable_interrupt();
cpu_int(LUNAIX_SCHED);
}
status_flags |= PEXITTERM;
goto done;
}
- if (proc->state == PS_STOPPED && (options & WUNTRACED)) {
+ if (proc->state == PS_READY && (options & WUNTRACED)) {
status_flags |= PEXITSTOP;
goto done;
}
llist_init_head(&proc->children);
llist_init_head(&proc->grp_member);
llist_init_head(&proc->sleep.sleepers);
+ waitq_init(&proc->waitqueue);
return proc;
}
llist_append(&process->parent->children, &process->siblings);
- process->state = PS_STOPPED;
+ process->state = PS_READY;
}
// from <kernel/process.c>
+++ /dev/null
-#include <lunaix/keyboard.h>
-#include <lunaix/lxconsole.h>
-#include <lunaix/proc.h>
-
-void
-_pconsole_main()
-{
- struct kdb_keyinfo_pkt keyevent;
- while (1) {
- if (!kbd_recv_key(&keyevent)) {
- yield();
- continue;
- }
- if ((keyevent.state & KBD_KEY_FPRESSED)) {
- if (keyevent.keycode == KEY_UP) {
- console_view_up();
- } else if (keyevent.keycode == KEY_DOWN) {
- console_view_down();
- }
- }
- }
-}
\ No newline at end of file