Skip to content

Commit

Permalink
Synchronization (#84)
Browse files Browse the repository at this point in the history
In the current situation, only one thread runs at a time since only one
CPU is enabled. Furthermore, threading is fully cooperative since
interrupts are always disabled, so threads can never be preempted.

This PR starts laying the foundations for multiprocessing by creating
the necessary synchronization primitives (spinlock, atomic
increment/decrement, "block thread and unlock", etc.) and by ensuring
they are used where needed.
  • Loading branch information
phaubertin authored Nov 19, 2024
1 parent 13ce324 commit b748a2f
Show file tree
Hide file tree
Showing 55 changed files with 1,589 additions and 608 deletions.
2 changes: 1 addition & 1 deletion doc/syscalls/destroy.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Description

Close a descriptor and destroy the kernel object to which it refers.
Destroy the kernel object to which a descriptor refers.

In order to use this function, the owner descriptor for the resource must be
specified. The owner descriptor is the descriptor that was specified in the
Expand Down
8 changes: 4 additions & 4 deletions include/jinue/shared/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,10 @@ typedef struct {
} jinue_mclone_args_t;

typedef struct {
int process;
int fd;
int perms;
uintptr_t cookie;
int process;
int fd;
int perms;
uintptr_t cookie;
} jinue_mint_args_t;

#endif
2 changes: 1 addition & 1 deletion include/kernel/application/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ int get_user_memory(const jinue_buffer_t *buffer);

int mclone(int src, int dest, const jinue_mclone_args_t *args);

int mint(int owner, const jinue_mint_args_t *mint_args);
int mint(int owner, const jinue_mint_args_t *args);

int mmap(int process_fd, const jinue_mmap_args_t *args);

Expand Down
66 changes: 48 additions & 18 deletions include/kernel/domain/entities/descriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,39 +38,69 @@
/* These flags are numbered downward starting at 31 to not conflict with PERM_... flags
* which share the same flags field. */

#define DESCRIPTOR_FLAG_NONE 0
#define DESC_FLAG_NONE 0

#define DESCRIPTOR_FLAG_IN_USE (1<<31)
#define DESC_FLAG_STATE1 (1<<31)

#define DESCRIPTOR_FLAG_DESTROYED (1<<30)
#define DESC_FLAG_STATE0 (1<<30)

#define DESCRIPTOR_FLAG_OWNER (1<<29)
#define DESC_FLAG_OWNER (1<<29)

static inline bool descriptor_is_in_use(descriptor_t *desc) {
return desc != NULL && (desc->flags & DESCRIPTOR_FLAG_IN_USE);
#define DESC_FLAG_STATE (DESC_FLAG_STATE1 | DESC_FLAG_STATE0)

#define DESC_STATE_FREE 0

#define DESC_STATE_RESERVED DESC_FLAG_STATE0

#define DESC_STATE_OPEN DESC_FLAG_STATE1

#define DESC_STATE_DESTROYED (DESC_FLAG_STATE1 | DESC_FLAG_STATE0)


static inline bool descriptor_is_free(const descriptor_t *desc) {
return (desc->flags & DESC_FLAG_STATE) == DESC_STATE_FREE;
}

static inline bool descriptor_is_reserved(const descriptor_t *desc) {
return (desc->flags & DESC_FLAG_STATE) == DESC_STATE_RESERVED;
}

static inline bool descriptor_is_open(const descriptor_t *desc) {
return (desc->flags & DESC_FLAG_STATE) == DESC_STATE_OPEN;
}

static inline bool descriptor_is_destroyed(const descriptor_t *desc) {
return (desc->flags & DESC_FLAG_STATE) == DESC_STATE_DESTROYED;
}

static inline bool descriptor_is_destroyed(descriptor_t *desc) {
return !!(desc->flags & DESCRIPTOR_FLAG_DESTROYED);
static inline bool descriptor_is_closeable(const descriptor_t *desc) {
return descriptor_is_open(desc) || descriptor_is_destroyed(desc);
}

static inline bool descriptor_is_owner(descriptor_t *desc) {
return !!(desc->flags & DESCRIPTOR_FLAG_OWNER);
static inline bool descriptor_is_owner(const descriptor_t *desc) {
return !!(desc->flags & DESC_FLAG_OWNER);
}

static inline bool descriptor_has_permissions(const descriptor_t *desc, int perms) {
return (desc->flags & perms) == perms;
}

void clear_descriptor(descriptor_t *desc);

int dereference_object_descriptor(
descriptor_t **pdesc,
process_t *process,
int fd);

int dereference_unused_descriptor(
descriptor_t **pdesc,
process_t *process,
int fd);
descriptor_t *pout,
process_t *process,
int fd);

void unreference_descriptor_object(descriptor_t *desc);

int reserve_free_descriptor(process_t *process, int fd);

void free_reserved_descriptor(process_t *process, int fd);

void open_descriptor(process_t *process, int fd, const descriptor_t *in);

int close_descriptor(process_t *process, int fd);

ipc_endpoint_t *get_endpoint_from_descriptor(descriptor_t *desc);

Expand Down
4 changes: 4 additions & 0 deletions include/kernel/domain/entities/endpoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@

extern const object_type_t *object_type_ipc_endpoint;

static inline object_header_t *endpoint_object(ipc_endpoint_t *endpoint) {
return &endpoint->header;
}

void initialize_endpoint_cache(void);

ipc_endpoint_t *construct_endpoint(void);
Expand Down
11 changes: 2 additions & 9 deletions include/kernel/domain/entities/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@

#define OBJECT_FLAG_DESTROYED (1<<0)


static inline void mark_object_destroyed(object_header_t *object) {
object->flags |= OBJECT_FLAG_DESTROYED;
}

static inline bool object_is_destroyed(object_header_t *object) {
return !!(object->flags & OBJECT_FLAG_DESTROYED);
}
Expand All @@ -55,10 +50,6 @@ static inline void init_object_header(object_header_t *object, const object_type
object->flags = OBJECT_FLAG_NONE;
}

static inline void add_ref_to_object(object_header_t *object) {
++object->ref_count;
}

void init_object_cache(slab_cache_t *cache, const object_type_t *type);

void open_object(object_header_t *object, const descriptor_t *desc);
Expand All @@ -67,6 +58,8 @@ void close_object(object_header_t *object, const descriptor_t *desc);

void destroy_object(object_header_t *object);

void add_ref_to_object(object_header_t *object);

void sub_ref_to_object(object_header_t *object);

#endif
4 changes: 4 additions & 0 deletions include/kernel/domain/entities/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@

extern const object_type_t *object_type_process;

static inline object_header_t *process_object(process_t *process) {
return &process->header;
}

void initialize_process_cache(void);

process_t *construct_process(void);
Expand Down
20 changes: 13 additions & 7 deletions include/kernel/domain/entities/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,29 @@

extern const object_type_t *object_type_thread;

static inline object_header_t *thread_object(thread_t *thread) {
return &thread->header;
}

thread_t *construct_thread(process_t *process);

void prepare_thread(thread_t *thread, const thread_params_t *params);

void ready_thread(thread_t *thread);

void switch_to_thread(thread_t *thread, bool blocked);
void run_first_thread(thread_t *thread);

void start_first_thread(thread_t *thread);
void run_thread(thread_t *thread);

void yield_current_thread(void);
void terminate_current_thread(void);

void block_current_thread(void);
void switch_to(thread_t *to);

void thread_is_starting(thread_t *thread);
void switch_to_and_block(thread_t *to);

void current_thread_is_exiting(void);
void block_and_unlock(spinlock_t *lock);

void yield_current_thread(void);

void set_thread_local_storage(thread_t *thread, addr_t addr, size_t size);

Expand Down
4 changes: 3 additions & 1 deletion include/kernel/infrastructure/i686/asm/eflags.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_EFLAGS_H
#define JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_EFLAGS_H

#define CPU_EFLAGS_ID (1<<21)
#define EFLAGS_ALWAYS_1 (1<<1)

#define EFLAGS_ID (1<<21)

#endif
2 changes: 2 additions & 0 deletions include/kernel/infrastructure/i686/exports.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,6 @@ typedef struct {
bool vga_enable;
} machine_config_t;

typedef struct { uint32_t lock; } spinlock_t;

#endif
2 changes: 1 addition & 1 deletion include/kernel/infrastructure/i686/percpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ static inline percpu_t *get_percpu_data(void) {
return (percpu_t *)get_gs_ptr( (uint32_t *)&zero->self );
}

static inline tss_t *get_tss(void) {
static inline tss_t *get_percpu_tss(void) {
return &get_percpu_data()->tss;
}

Expand Down
1 change: 0 additions & 1 deletion include/kernel/infrastructure/i686/pmap/private.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ void destroy_page_directory(void *page_directory, unsigned int last_index);
*
* @param pte page table or page directory entry
* @return true if page is present in memory, false otherwise
*
*/
static inline bool pte_is_present(const pte_t *pte) {
/* Micro-optimization: both flags we are interested in are in the lower four
Expand Down
5 changes: 1 addition & 4 deletions include/kernel/infrastructure/i686/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@
#include <kernel/machine/types.h>
#include <stdbool.h>

void switch_thread_stack(
machine_thread_t *from_ctx,
machine_thread_t *to_ctx,
bool destroy_from);
void switch_thread_stack(machine_thread_t *from, machine_thread_t *to);

#endif
8 changes: 0 additions & 8 deletions include/kernel/infrastructure/i686/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,4 @@ struct percpu_t {

typedef struct percpu_t percpu_t;

typedef struct {
uint32_t edi;
uint32_t esi;
uint32_t ebx;
uint32_t ebp;
uint32_t eip;
} kernel_context_t;

#endif
39 changes: 39 additions & 0 deletions include/kernel/machine/atomic.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2024 Philippe Aubertin.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the author nor the names of other contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef JINUE_KERNEL_MACHINE_ATOMIC_H
#define JINUE_KERNEL_MACHINE_ATOMIC_H

int add_atomic(int *value, int increment);

int or_atomic(int *value, int mask);

#endif
2 changes: 0 additions & 2 deletions include/kernel/machine/pmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,4 @@ bool machine_clone_userspace_mapping(

kern_paddr_t machine_lookup_kernel_paddr(void *addr);

void machine_switch_to_kernel_addr_space(void);

#endif
46 changes: 46 additions & 0 deletions include/kernel/machine/spinlock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (C) 2024 Philippe Aubertin.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the author nor the names of other contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef JINUE_KERNEL_MACHINE_SPINLOCK_H
#define JINUE_KERNEL_MACHINE_SPINLOCK_H

#include <kernel/machine/types.h>

#define SPINLOCK_STATIC { .lock = 0 }

void init_spinlock(spinlock_t *lock);

void spin_lock(spinlock_t *lock);

void spin_unlock(spinlock_t *lock);

#endif

6 changes: 5 additions & 1 deletion include/kernel/machine/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ thread_t *machine_alloc_thread(void);

void machine_free_thread(thread_t *thread);

void machine_switch_thread(thread_t *from, thread_t *to, bool destroy_from);
void machine_switch_thread(thread_t *from, thread_t *to);

void machine_switch_and_unref_thread(thread_t *from, thread_t *to);

void machine_switch_thread_and_unlock(thread_t *from, thread_t *to, spinlock_t *lock);

#endif
2 changes: 1 addition & 1 deletion include/kernel/machine/tls.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@

#include <kernel/types.h>

void machine_set_tls(const thread_t *thread);
void machine_set_thread_local_storage(const thread_t *thread);

#endif
Loading

0 comments on commit b748a2f

Please sign in to comment.