<commit_before>#include <kernel/ksem.h>
#include <kernel/wait.h>
#include <kernel/thread.h>
#include <errno.h>
#include <kernel/scheduler.h>
#include <kernel/spinlock.h>
#include <kernel/printk.h>
#include <kernel/syscall.h>
#include <kernel/ktime.h>
#include <export.h>
#include <trace.h>

static void ksem_timeout_callback(void *arg)
{
	struct thread *thread = (struct thread *)arg;

	if (thread->state == THREAD_BLOCKED) {
		thread->err_wait = -ETIMEDOUT;
		wait_queue_wake_thread(thread);
	}
}

int ksem_init(struct semaphore *sem, int value)
{
	int ret = 0;

	if (!sem) {
		ret = -EINVAL;
		goto err;
	}

	sem->value = value;
	sem->count = 0;

	wait_queue_init(&sem->wait);

	trace_sem_create(sem);

err:
	return ret;
}

int ksem_wait(struct semaphore *sem)
{
	int ret = 0;
	unsigned long irqstate;

	arch_interrupt_save(&irqstate, SPIN_LOCK_FLAG_IRQ);

	if (!sem) {
		ret = -EINVAL;
		goto err;
	}

	sem->count--;

	trace_sem_wait(sem);

	if (sem->count < 0) {
		debug_printk("unable to got sem (%p)(%d)\r\n", sem, sem->count);

		ret = wait_queue_block_irqstate(&sem->wait, &irqstate);
	}

err:
	arch_interrupt_restore(irqstate, SPIN_LOCK_FLAG_IRQ);
	return ret;
}

int ksem_timedwait(struct semaphore *sem, int timeout)
{
	int ret = 0;
	struct thread *thread = get_current_thread();

	thread->err_wait = 0;
	ktime_oneshot(timeout, ksem_timeout_callback, thread);
	
	ret = ksem_wait(sem);
	if (ret)
		goto err;

	ret = thread->err_wait;

err:
	return ret;
}

int ksem_post(struct semaphore *sem)
{
	int ret = 0;
	unsigned long irqstate;

	arch_interrupt_save(&irqstate, SPIN_LOCK_FLAG_IRQ);

	if (!sem) {
		ret = -EINVAL;
		goto err;
	}

	sem->count++;

	if (sem->count > sem->value)
		sem->count = sem->value;

	trace_sem_post(sem);

	if (sem->count <= 0)
		ret = wait_queue_wake_irqstate(&sem->wait, &irqstate);

err:
	arch_interrupt_restore(irqstate, SPIN_LOCK_FLAG_IRQ);
	return ret;
}

int ksem_post_isr(struct semaphore *sem)
{
	int ret = 0;

	if (!sem) {
		ret = -EINVAL;
		goto err;
	}

	sem->count++;

	if (sem->count > sem->value)
		sem->count = sem->value;

	trace_sem_post(sem);

	if (sem->count <= 0)
		ret = wait_queue_wake_isr(&sem->wait);

err:
	return ret;
}
<commit_msg>kernel: ksem: use wait_queue_block_timed in ksem_timedwait<commit_after>#include <kernel/ksem.h>
#include <kernel/wait.h>
#include <kernel/thread.h>
#include <errno.h>
#include <kernel/scheduler.h>
#include <kernel/spinlock.h>
#include <kernel/printk.h>
#include <kernel/syscall.h>
#include <kernel/ktime.h>
#include <export.h>
#include <trace.h>

int ksem_init(struct semaphore *sem, int value)
{
	int ret = 0;

	if (!sem) {
		ret = -EINVAL;
		goto err;
	}

	sem->value = value;
	sem->count = 0;

	wait_queue_init(&sem->wait);

	trace_sem_create(sem);

err:
	return ret;
}

int ksem_wait(struct semaphore *sem)
{
	int ret = 0;
	unsigned long irqstate;

	arch_interrupt_save(&irqstate, SPIN_LOCK_FLAG_IRQ);

	if (!sem) {
		ret = -EINVAL;
		goto err;
	}

	sem->count--;

	trace_sem_wait(sem);

	if (sem->count < 0) {
		debug_printk("unable to got sem (%p)(%d)\r\n", sem, sem->count);

		ret = wait_queue_block_irqstate(&sem->wait, &irqstate);
	}

err:
	arch_interrupt_restore(irqstate, SPIN_LOCK_FLAG_IRQ);
	return ret;
}

int ksem_timedwait(struct semaphore *sem, int timeout)
{
	int ret = 0;
	unsigned long irqstate;
	struct thread *thread = get_current_thread();

	arch_interrupt_save(&irqstate, SPIN_LOCK_FLAG_IRQ);

	if (!sem) {
		ret = -EINVAL;
		goto err;
	}

	sem->count--;

	trace_sem_wait(sem);

	if (sem->count < 0) {
		debug_printk("unable to got sem (%p)(%d)\r\n", sem, sem->count);

		ret = wait_queue_block_timed(&sem->wait, timeout);
	}

	ret = thread->err_wait;

err:
	arch_interrupt_restore(irqstate, SPIN_LOCK_FLAG_IRQ);
	return ret;
}

int ksem_post(struct semaphore *sem)
{
	int ret = 0;
	unsigned long irqstate;

	arch_interrupt_save(&irqstate, SPIN_LOCK_FLAG_IRQ);

	if (!sem) {
		ret = -EINVAL;
		goto err;
	}

	sem->count++;

	if (sem->count > sem->value)
		sem->count = sem->value;

	trace_sem_post(sem);

	if (sem->count <= 0)
		ret = wait_queue_wake_irqstate(&sem->wait, &irqstate);

err:
	arch_interrupt_restore(irqstate, SPIN_LOCK_FLAG_IRQ);
	return ret;
}

int ksem_post_isr(struct semaphore *sem)
{
	int ret = 0;

	if (!sem) {
		ret = -EINVAL;
		goto err;
	}

	sem->count++;

	if (sem->count > sem->value)
		sem->count = sem->value;

	trace_sem_post(sem);

	if (sem->count <= 0)
		ret = wait_queue_wake_isr(&sem->wait);

err:
	return ret;
}

{'fraction_non_alphanumeric': 0.1553615401835684, 'fraction_numerical': 0.0044772778150884264, 'mean_word_length': 4.250293772032903, 'pattern_counts': {'":': 0, '<': 32, '<?xml version=': 0, '>': 80, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '564856', 'n_tokens_mistral': 1920, 'n_tokens_neox': 1816, 'n_words': 392}