mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 23:18:21 +00:00
vioblk: fix possible lost wakeup
This commit is contained in:
@@ -23,7 +23,7 @@ typedef struct {
|
|||||||
dpc_t queuedpc;
|
dpc_t queuedpc;
|
||||||
spinlock_t queuelock;
|
spinlock_t queuelock;
|
||||||
semaphore_t queuesem;
|
semaphore_t queuesem;
|
||||||
event_t *queuewaiting[QUEUE_MAX_SIZE / 2];
|
thread_t *queuewaiting[QUEUE_MAX_SIZE / 2];
|
||||||
} vioblkdev_t;
|
} vioblkdev_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -46,7 +46,7 @@ static void vioblk_dpc(context_t *context, dpcarg_t arg) {
|
|||||||
int idx = blkdev->queue.lastusedindex++ % blkdev->queue.size;
|
int idx = blkdev->queue.lastusedindex++ % blkdev->queue.size;
|
||||||
int buffidx = VIO_QUEUE_DEV_RING(&blkdev->queue)[idx].index;
|
int buffidx = VIO_QUEUE_DEV_RING(&blkdev->queue)[idx].index;
|
||||||
__assert(blkdev->queuewaiting[buffidx / 2]);
|
__assert(blkdev->queuewaiting[buffidx / 2]);
|
||||||
event_signal(blkdev->queuewaiting[buffidx / 2]);
|
sched_wakeup(blkdev->queuewaiting[buffidx / 2], SCHED_WAKEUP_REASON_NORMAL);
|
||||||
blkdev->queuewaiting[buffidx / 2] = NULL;
|
blkdev->queuewaiting[buffidx / 2] = NULL;
|
||||||
buffers[buffidx].address = 0;
|
buffers[buffidx].address = 0;
|
||||||
buffers[buffidx + 1].address = 0;
|
buffers[buffidx + 1].address = 0;
|
||||||
@@ -90,12 +90,13 @@ static void vioblk_enqueue(vioblkdev_t *blkdev, void *driver, size_t driverlen,
|
|||||||
size_t driveridx = VIO_QUEUE_DRV_IDX(&blkdev->queue)++;
|
size_t driveridx = VIO_QUEUE_DRV_IDX(&blkdev->queue)++;
|
||||||
VIO_QUEUE_DRV_RING(&blkdev->queue)[driveridx % blkdev->queue.size] = idx;
|
VIO_QUEUE_DRV_RING(&blkdev->queue)[driveridx % blkdev->queue.size] = idx;
|
||||||
|
|
||||||
blkdev->queuewaiting[idx / 2] = &event;
|
sched_preparesleep(false);
|
||||||
|
blkdev->queuewaiting[idx / 2] = _cpu()->thread;
|
||||||
|
|
||||||
*blkdev->queue.notify = 0;
|
*blkdev->queue.notify = 0;
|
||||||
spinlock_release(&blkdev->queuelock);
|
spinlock_release(&blkdev->queuelock);
|
||||||
|
|
||||||
event_wait(&event, false);
|
sched_yield();
|
||||||
|
|
||||||
interrupt_set(intstatus);
|
interrupt_set(intstatus);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user