Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3cf8ae04f1 | |||
| 25b4a34f1b | |||
| 206d0ebf05 | |||
| a64ce2f81d | |||
| 5aaddd467c | |||
| 0fd6bec4a3 | |||
| c1cc7e366a |
@@ -38,7 +38,7 @@ PROJECT_NAME = MentOS
|
|||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = 0.4.0
|
PROJECT_NUMBER = 0.5.2
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer a
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
Call `man` to have a list of all the commands.
|
||||||
+87
-97
@@ -19,8 +19,7 @@ typedef struct list_head {
|
|||||||
/// @param ptr The &list_head pointer.
|
/// @param ptr The &list_head pointer.
|
||||||
/// @param type The type of the struct this is embedded in.
|
/// @param type The type of the struct this is embedded in.
|
||||||
/// @param member The name of the list_head within the struct.
|
/// @param member The name of the list_head within the struct.
|
||||||
#define list_entry(ptr, type, member) \
|
#define list_entry(ptr, type, member) container_of(ptr, type, member)
|
||||||
container_of(ptr, type, member)
|
|
||||||
|
|
||||||
/// @brief Iterates over a list.
|
/// @brief Iterates over a list.
|
||||||
/// @param pos The &list_head to use as a loop cursor.
|
/// @param pos The &list_head to use as a loop cursor.
|
||||||
@@ -49,124 +48,115 @@ typedef struct list_head {
|
|||||||
for (list_head * (pos) = (head)->next; (pos) != (head); (pos) = (pos)->next)
|
for (list_head * (pos) = (head)->next; (pos) != (head); (pos) = (pos)->next)
|
||||||
|
|
||||||
/// @brief Initializes the list_head.
|
/// @brief Initializes the list_head.
|
||||||
/// @param head The head for your list.
|
/// @param head The head of your list.
|
||||||
#define list_head_init(head) (head)->next = (head)->prev = (head)
|
static inline void list_head_init(list_head *head)
|
||||||
|
|
||||||
/// @brief Initializes the list_head.
|
|
||||||
/// @param head The head for your list.
|
|
||||||
#define list_head_size(head) \
|
|
||||||
({ \
|
|
||||||
unsigned __list_head_size = 0; \
|
|
||||||
list_for_each_decl(it, head) __list_head_size += 1; \
|
|
||||||
__list_head_size; \
|
|
||||||
})
|
|
||||||
|
|
||||||
/// @brief Insert element l2 after l1.
|
|
||||||
static inline void list_head_insert_after(list_head *l1, list_head *l2)
|
|
||||||
{
|
{
|
||||||
// [La]->l1 La<-[l1]->Lb <-[l2]-> l1<-[Lb]
|
head->next = head->prev = head;
|
||||||
|
|
||||||
list_head *l1_next = l1->next;
|
|
||||||
// [La]->l1 La<-[l1]->l2 <-[l2]-> l1<-[Lb]
|
|
||||||
l1->next = l2;
|
|
||||||
// [La]->l1 La<-[l1]->l2 l1<-[l2]-> l1<-[Lb]
|
|
||||||
l2->prev = l1;
|
|
||||||
// [La]->l1 La<-[l1]->l2 l1<-[l2]->Lb l1<-[Lb]
|
|
||||||
l2->next = l1_next;
|
|
||||||
// [La]->l1 La<-[l1]->l2 l1<-[l2]->Lb l2<-[Lb]
|
|
||||||
l1_next->prev = l2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Insert element l2 before l1.
|
|
||||||
static inline void list_head_insert_before(list_head *l1, list_head *l2)
|
|
||||||
{
|
|
||||||
// [La]->l1 [l2] La<-[l1]->Lb l1<-[Lb]
|
|
||||||
|
|
||||||
list_head *l1_prev = l1->prev;
|
|
||||||
// [La]->l2 [l2] La<-[l1]->Lb l1<-[Lb]
|
|
||||||
l1_prev->next = l2;
|
|
||||||
// [La]->l2 La<-[l2] La<-[l1]->Lb l1<-[Lb]
|
|
||||||
l2->prev = l1_prev;
|
|
||||||
// [La]->l2 La<-[l2]->l1 La<-[l1]->Lb l1<-[Lb]
|
|
||||||
l2->next = l1;
|
|
||||||
// [La]->l2 La<-[l2]->l1 l2<-[l1]->Lb l1<-[Lb]
|
|
||||||
l1->prev = l2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Remove l from the list.
|
|
||||||
/// @param l The element to remove.
|
|
||||||
static inline void list_head_del(list_head *l)
|
|
||||||
{
|
|
||||||
// [La]->l La<-[l]->Lb l<-[Lb]
|
|
||||||
|
|
||||||
// [La]->Lb La<-[l]->Lb l<-[Lb]
|
|
||||||
l->prev->next = l->next;
|
|
||||||
// [La]->Lb La<-[l]->Lb La<-[Lb]
|
|
||||||
l->next->prev = l->prev;
|
|
||||||
// [La]->Lb l<-[l]->l La<-[Lb]
|
|
||||||
l->next = l->prev = l;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Tests whether the given list is empty.
|
/// @brief Tests whether the given list is empty.
|
||||||
/// @param head The list to check.
|
/// @param head The list to check.
|
||||||
/// @return 1 if empty, 0 otherwise.
|
/// @return 1 if empty, 0 otherwise.
|
||||||
static inline int list_head_empty(list_head const *head)
|
static inline int list_head_empty(const list_head *head)
|
||||||
{
|
{
|
||||||
return head->next == head;
|
return head->next == head;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert a new entry between two known consecutive entries.
|
/// @brief Initializes the list_head.
|
||||||
static inline void __list_add(list_head *new, list_head *prev, list_head *next)
|
/// @param head The head for your list.
|
||||||
|
static inline unsigned list_head_size(const list_head *head)
|
||||||
{
|
{
|
||||||
// [prev]-> <-[new]-> <-[next]
|
unsigned size = 0;
|
||||||
|
if (!list_head_empty(head))
|
||||||
// [prev]-> <-[new]-> new<-[next]
|
list_for_each_decl(it, head) size += 1;
|
||||||
next->prev = new;
|
return size;
|
||||||
// [prev]-> <-[new]->next new<-[next]
|
|
||||||
new->next = next;
|
|
||||||
// [prev]-> prev<-[new]->next new<-[next]
|
|
||||||
new->prev = prev;
|
|
||||||
// [prev]->new prev<-[new]->next new<-[next]
|
|
||||||
prev->next = new;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Insert element l2 before l1.
|
/// @brief Insert the new entry after the given location.
|
||||||
static inline void list_head_add(list_head *new, list_head *head)
|
/// @param new_entry the new element we want to insert.
|
||||||
|
/// @param location the element after which we insert.
|
||||||
|
static inline void list_head_insert_after(list_head *new_entry, list_head *location)
|
||||||
{
|
{
|
||||||
__list_add(new, head, head->next);
|
// We store the old `next` element.
|
||||||
|
list_head *old_next = location->next;
|
||||||
|
// We insert our element.
|
||||||
|
location->next = new_entry;
|
||||||
|
// We update the `previous` link of our new entry.
|
||||||
|
new_entry->prev = location;
|
||||||
|
// We update the `next` link of our new entry.
|
||||||
|
new_entry->next = old_next;
|
||||||
|
// We link the previously `next` element to our new entry.
|
||||||
|
old_next->prev = new_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Insert element l2 before l1.
|
/// @brief Insert the new entry before the given location.
|
||||||
static inline void list_head_add_tail(list_head *new, list_head *head)
|
/// @param new_entry the new element we want to insert.
|
||||||
|
/// @param location the element after which we insert.
|
||||||
|
static inline void list_head_insert_before(list_head *new_entry, list_head *location)
|
||||||
{
|
{
|
||||||
__list_add(new, head->prev, head);
|
// We store the old `previous` element.
|
||||||
|
list_head *old_prev = location->prev;
|
||||||
|
// We link the old `previous` element to our new entry.
|
||||||
|
old_prev->next = new_entry;
|
||||||
|
// We update the `previous` link of our new entry.
|
||||||
|
new_entry->prev = old_prev;
|
||||||
|
// We update the `next` link of our new entry.
|
||||||
|
new_entry->next = location;
|
||||||
|
// Finally, we close the link with the old insertion location element.
|
||||||
|
location->prev = new_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Removes an element from the list pointer, it's used when we have a possibly
|
/// @brief Removes the given entry from the list it is contained in.
|
||||||
/// null list pointer and want to pop an element from it
|
/// @param entry the entry we want to remove.
|
||||||
static inline list_head *list_head_pop(list_head *listp)
|
static inline void list_head_remove(list_head *entry)
|
||||||
{
|
{
|
||||||
if (list_head_empty(listp))
|
// Check if the element is actually in a list.
|
||||||
return NULL;
|
if (!list_head_empty(entry)) {
|
||||||
|
// We link the `previous` element to the `next` one.
|
||||||
list_head *value = listp->next;
|
entry->prev->next = entry->next;
|
||||||
list_head_del(listp->next);
|
// We link the `next` element to the `previous` one.
|
||||||
|
entry->next->prev = entry->prev;
|
||||||
return value;
|
// We initialize the entry again.
|
||||||
|
list_head_init(entry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline list_head *list_head_front(list_head *listp)
|
/// @brief Removes an element from the list, it's used when we have a possibly
|
||||||
|
/// null list pointer and want to pop an element from it.
|
||||||
|
/// @param head the head of the list.
|
||||||
|
/// @return a list_head pointing to the element we removed, NULL on failure.
|
||||||
|
static inline list_head *list_head_pop(list_head *head)
|
||||||
{
|
{
|
||||||
return listp->next;
|
// Check if the list is not empty.
|
||||||
|
if (!list_head_empty(head)) {
|
||||||
|
// Store the pointer.
|
||||||
|
list_head *value = head->next;
|
||||||
|
// Remove the element from the list.
|
||||||
|
list_head_remove(head->next);
|
||||||
|
// Return the pointer to the element.
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Merges the elements of l2, into the elements of l1.
|
/// @brief Append the `secondary` list at the end of the `main` list.
|
||||||
static inline void list_head_merge(list_head *l1, list_head *l2)
|
/// @param main the main list where we append the secondary list.
|
||||||
|
/// @param secondary the secondary list, which gets appended, and re-initialized as empty.
|
||||||
|
static inline void list_head_append(list_head *main, list_head *secondary)
|
||||||
{
|
{
|
||||||
l1->prev->next = l2->next;
|
// Check that both lists are actually filled with entries.
|
||||||
l2->next->prev = l1->prev;
|
if (!list_head_empty(main) && !list_head_empty(secondary)) {
|
||||||
l2->prev->next = l1;
|
// Connect the last element of the main list to the first one of the secondary list.
|
||||||
l1->prev = l2->prev;
|
main->prev->next = secondary->next;
|
||||||
// Initialize the second list.
|
// Connect the first element of the secondary list to the last one of the main list.
|
||||||
list_head_init(l2);
|
secondary->next->prev = main->prev;
|
||||||
}
|
|
||||||
|
// Connect the last element of the secondary list to our main.
|
||||||
|
secondary->prev->next = main;
|
||||||
|
// Connect our main to the last element of the secondary list.
|
||||||
|
main->prev = secondary->prev;
|
||||||
|
|
||||||
|
// Re-initialize the secondary list.
|
||||||
|
list_head_init(secondary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,10 +18,10 @@
|
|||||||
#define OS_MAJOR_VERSION 0
|
#define OS_MAJOR_VERSION 0
|
||||||
|
|
||||||
/// Minor version of the operating system.
|
/// Minor version of the operating system.
|
||||||
#define OS_MINOR_VERSION 4
|
#define OS_MINOR_VERSION 5
|
||||||
|
|
||||||
/// Micro version of the operating system.
|
/// Micro version of the operating system.
|
||||||
#define OS_MICRO_VERSION 0
|
#define OS_MICRO_VERSION 2
|
||||||
|
|
||||||
/// Helper to transform the given argument into a string.
|
/// Helper to transform the given argument into a string.
|
||||||
#define OS_STR_HELPER(x) #x
|
#define OS_STR_HELPER(x) #x
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ static inline irq_struct_t *__irq_struct_alloc()
|
|||||||
/// @brief Destroys an irq struct.
|
/// @brief Destroys an irq struct.
|
||||||
static inline void __irq_struct_dealloc(irq_struct_t *irq_struct)
|
static inline void __irq_struct_dealloc(irq_struct_t *irq_struct)
|
||||||
{
|
{
|
||||||
list_head_del(&irq_struct->siblings);
|
list_head_remove(&irq_struct->siblings);
|
||||||
kmem_cache_free(irq_struct);
|
kmem_cache_free(irq_struct);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ int irq_install_handler(unsigned i, interrupt_handler_t handler, char *descripti
|
|||||||
irq_struct->description = description;
|
irq_struct->description = description;
|
||||||
irq_struct->handler = handler;
|
irq_struct->handler = handler;
|
||||||
// Add the handler to the list of his siblings.
|
// Add the handler to the list of his siblings.
|
||||||
list_head_add_tail(&irq_struct->siblings, &shared_interrupt_handlers[i]);
|
list_head_insert_before(&irq_struct->siblings, &shared_interrupt_handlers[i]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ int irq_uninstall_handler(unsigned i, interrupt_handler_t handler)
|
|||||||
irq_struct_t *irq_struct = list_entry(it, irq_struct_t, siblings);
|
irq_struct_t *irq_struct = list_entry(it, irq_struct_t, siblings);
|
||||||
assert(irq_struct && "Something went wrong.");
|
assert(irq_struct && "Something went wrong.");
|
||||||
if (irq_struct->handler == handler) {
|
if (irq_struct->handler == handler) {
|
||||||
list_head_del(&irq_struct->siblings);
|
list_head_remove(&irq_struct->siblings);
|
||||||
}
|
}
|
||||||
__irq_struct_dealloc(irq_struct);
|
__irq_struct_dealloc(irq_struct);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2259,7 +2259,7 @@ static vfs_file_t *ext2_creat(const char *path, mode_t permission)
|
|||||||
goto close_parent_return_null;
|
goto close_parent_return_null;
|
||||||
}
|
}
|
||||||
// Add the vfs_file to the list of associated files.
|
// Add the vfs_file to the list of associated files.
|
||||||
list_head_add_tail(&file->siblings, &fs->opened_files);
|
list_head_insert_before(&file->siblings, &fs->opened_files);
|
||||||
}
|
}
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
@@ -2378,7 +2378,7 @@ static vfs_file_t *ext2_open(const char *path, int flags, mode_t mode)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
// Add the vfs_file to the list of associated files.
|
// Add the vfs_file to the list of associated files.
|
||||||
list_head_add_tail(&file->siblings, &fs->opened_files);
|
list_head_insert_before(&file->siblings, &fs->opened_files);
|
||||||
}
|
}
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
@@ -2487,7 +2487,7 @@ static int ext2_close(vfs_file_t *file)
|
|||||||
}
|
}
|
||||||
pr_debug("ext2_close(ino: %d, file: \"%s\")\n", file->ino, file->name);
|
pr_debug("ext2_close(ino: %d, file: \"%s\")\n", file->ino, file->name);
|
||||||
// Remove the file from the list of opened files.
|
// Remove the file from the list of opened files.
|
||||||
list_head_del(&file->siblings);
|
list_head_remove(&file->siblings);
|
||||||
// Free the cache.
|
// Free the cache.
|
||||||
kmem_cache_free(file);
|
kmem_cache_free(file);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -3040,7 +3040,7 @@ static vfs_file_t *ext2_mount(vfs_file_t *block_device, const char *path)
|
|||||||
goto free_all;
|
goto free_all;
|
||||||
}
|
}
|
||||||
// Add the root to the list of opened files.
|
// Add the root to the list of opened files.
|
||||||
list_head_add_tail(&fs->root->siblings, &fs->opened_files);
|
list_head_insert_before(&fs->root->siblings, &fs->opened_files);
|
||||||
|
|
||||||
// Dump the filesystem details for debugging.
|
// Dump the filesystem details for debugging.
|
||||||
ext2_dump_filesystem(fs);
|
ext2_dump_filesystem(fs);
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ static inline procfs_file_t *procfs_create_file(const char *path, unsigned flags
|
|||||||
// List of all the PROCFS files.
|
// List of all the PROCFS files.
|
||||||
list_head_init(&procfs_file->siblings);
|
list_head_init(&procfs_file->siblings);
|
||||||
// Add the file to the list of opened files.
|
// Add the file to the list of opened files.
|
||||||
list_head_add_tail(&procfs_file->siblings, &fs.files);
|
list_head_insert_before(&procfs_file->siblings, &fs.files);
|
||||||
// Time of last access.
|
// Time of last access.
|
||||||
procfs_file->atime = sys_time(NULL);
|
procfs_file->atime = sys_time(NULL);
|
||||||
// Time of last data modification.
|
// Time of last data modification.
|
||||||
@@ -282,7 +282,7 @@ static inline int procfs_destroy_file(procfs_file_t *procfs_file)
|
|||||||
}
|
}
|
||||||
pr_debug("procfs_destroy_file(%p) `%s`\n", procfs_file, procfs_file->name);
|
pr_debug("procfs_destroy_file(%p) `%s`\n", procfs_file, procfs_file->name);
|
||||||
// Remove the file from the list of opened files.
|
// Remove the file from the list of opened files.
|
||||||
list_head_del(&procfs_file->siblings);
|
list_head_remove(&procfs_file->siblings);
|
||||||
// Free the cache.
|
// Free the cache.
|
||||||
kmem_cache_free(procfs_file);
|
kmem_cache_free(procfs_file);
|
||||||
// Decrease the number of files.
|
// Decrease the number of files.
|
||||||
@@ -467,7 +467,7 @@ static vfs_file_t *procfs_open(const char *path, int flags, mode_t mode)
|
|||||||
// Update file access.
|
// Update file access.
|
||||||
procfs_file->atime = sys_time(NULL);
|
procfs_file->atime = sys_time(NULL);
|
||||||
// Add the vfs_file to the list of associated files.
|
// Add the vfs_file to the list of associated files.
|
||||||
list_head_add_tail(&vfs_file->siblings, &procfs_file->files);
|
list_head_insert_before(&vfs_file->siblings, &procfs_file->files);
|
||||||
return vfs_file;
|
return vfs_file;
|
||||||
}
|
}
|
||||||
// Check if the user did not want to open a directory, but it is.
|
// Check if the user did not want to open a directory, but it is.
|
||||||
@@ -486,7 +486,7 @@ static vfs_file_t *procfs_open(const char *path, int flags, mode_t mode)
|
|||||||
// Update file access.
|
// Update file access.
|
||||||
procfs_file->atime = sys_time(NULL);
|
procfs_file->atime = sys_time(NULL);
|
||||||
// Add the vfs_file to the list of associated files.
|
// Add the vfs_file to the list of associated files.
|
||||||
list_head_add_tail(&vfs_file->siblings, &procfs_file->files);
|
list_head_insert_before(&vfs_file->siblings, &procfs_file->files);
|
||||||
return vfs_file;
|
return vfs_file;
|
||||||
}
|
}
|
||||||
// When both O_CREAT and O_DIRECTORY are specified in flags and the file
|
// When both O_CREAT and O_DIRECTORY are specified in flags and the file
|
||||||
@@ -508,7 +508,7 @@ static vfs_file_t *procfs_open(const char *path, int flags, mode_t mode)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
// Add the vfs_file to the list of associated files.
|
// Add the vfs_file to the list of associated files.
|
||||||
list_head_add_tail(&vfs_file->siblings, &procfs_file->files);
|
list_head_insert_before(&vfs_file->siblings, &procfs_file->files);
|
||||||
pr_debug("Created file `%s`.\n", path);
|
pr_debug("Created file `%s`.\n", path);
|
||||||
return vfs_file;
|
return vfs_file;
|
||||||
}
|
}
|
||||||
@@ -523,7 +523,7 @@ static int procfs_close(vfs_file_t *file)
|
|||||||
assert(file && "Received null file.");
|
assert(file && "Received null file.");
|
||||||
//pr_debug("procfs_close(%p): VFS file : %p\n", file, file);
|
//pr_debug("procfs_close(%p): VFS file : %p\n", file, file);
|
||||||
// Remove the file from the list of `files` inside its corresponding `procfs_file_t`.
|
// Remove the file from the list of `files` inside its corresponding `procfs_file_t`.
|
||||||
list_head_del(&file->siblings);
|
list_head_remove(&file->siblings);
|
||||||
// Free the memory of the file.
|
// Free the memory of the file.
|
||||||
kmem_cache_free(file);
|
kmem_cache_free(file);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -778,7 +778,7 @@ static vfs_file_t *procfs_mount_callback(const char *path, const char *device)
|
|||||||
vfs_file_t *vfs_file = procfs_create_file_struct(procfs_file);
|
vfs_file_t *vfs_file = procfs_create_file_struct(procfs_file);
|
||||||
assert(vfs_file && "Failed to create vfs_file.");
|
assert(vfs_file && "Failed to create vfs_file.");
|
||||||
// Add the vfs_file to the list of associated files.
|
// Add the vfs_file to the list of associated files.
|
||||||
list_head_add_tail(&vfs_file->siblings, &procfs_file->files);
|
list_head_insert_before(&vfs_file->siblings, &procfs_file->files);
|
||||||
// Initialize the proc_root.
|
// Initialize the proc_root.
|
||||||
return vfs_file;
|
return vfs_file;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -416,7 +416,7 @@ int vfs_mount(const char *path, vfs_file_t *new_fs_root)
|
|||||||
// Set the pointer.
|
// Set the pointer.
|
||||||
sb->root = new_fs_root;
|
sb->root = new_fs_root;
|
||||||
// Add to the list.
|
// Add to the list.
|
||||||
list_head_add(&sb->mounts, &vfs_super_blocks);
|
list_head_insert_after(&sb->mounts, &vfs_super_blocks);
|
||||||
}
|
}
|
||||||
spinlock_unlock(&vfs_spinlock);
|
spinlock_unlock(&vfs_spinlock);
|
||||||
pr_debug("Correctly mounted '%s' on '%s'...\n", new_fs_root->name, path);
|
pr_debug("Correctly mounted '%s' on '%s'...\n", new_fs_root->name, path);
|
||||||
|
|||||||
@@ -314,7 +314,7 @@ static void __add_timer_tvec_base(tvec_base_t *base, struct timer_list *timer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pr_debug("Adding timer at time_index: %d in tv%d\n", index, tv_index);
|
pr_debug("Adding timer at time_index: %d in tv%d\n", index, tv_index);
|
||||||
list_head_add_tail(&timer->entry, vec);
|
list_head_insert_before(&timer->entry, vec);
|
||||||
|
|
||||||
#ifdef ENABLE_REAL_TIMER_SYSTEM_DUMP
|
#ifdef ENABLE_REAL_TIMER_SYSTEM_DUMP
|
||||||
__dump_all_tvec_slots(base);
|
__dump_all_tvec_slots(base);
|
||||||
@@ -347,7 +347,7 @@ static void __rem_timer_tvec_base(tvec_base_t *base, struct timer_list *timer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pr_debug("Removing timer at time_index: %d in tv%d\n", index, tv_index);
|
pr_debug("Removing timer at time_index: %d in tv%d\n", index, tv_index);
|
||||||
list_head_del(&timer->entry);
|
list_head_remove(&timer->entry);
|
||||||
|
|
||||||
#ifdef ENABLE_REAL_TIMER_SYSTEM_DUMP
|
#ifdef ENABLE_REAL_TIMER_SYSTEM_DUMP
|
||||||
__dump_all_tvec_slots(base);
|
__dump_all_tvec_slots(base);
|
||||||
@@ -364,7 +364,7 @@ static int cascate(tvec_base_t *base, timer_vec *tv, int time_index, int tv_inde
|
|||||||
struct list_head *it, *tmp;
|
struct list_head *it, *tmp;
|
||||||
list_for_each_safe (it, tmp, tv->vec + time_index) {
|
list_for_each_safe (it, tmp, tv->vec + time_index) {
|
||||||
struct timer_list *timer = list_entry(it, struct timer_list, entry);
|
struct timer_list *timer = list_entry(it, struct timer_list, entry);
|
||||||
list_head_del(it);
|
list_head_remove(it);
|
||||||
|
|
||||||
__add_timer_tvec_base(base, timer);
|
__add_timer_tvec_base(base, timer);
|
||||||
}
|
}
|
||||||
@@ -425,7 +425,7 @@ void run_timer_softirq()
|
|||||||
spinlock_lock(&base->lock);
|
spinlock_lock(&base->lock);
|
||||||
|
|
||||||
// Removes timer from list
|
// Removes timer from list
|
||||||
list_head_del(it);
|
list_head_remove(it);
|
||||||
kfree(timer);
|
kfree(timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -453,7 +453,7 @@ void run_timer_softirq()
|
|||||||
|
|
||||||
// Removes timer from list
|
// Removes timer from list
|
||||||
pr_debug("Removing dynamic timer...\n");
|
pr_debug("Removing dynamic timer...\n");
|
||||||
list_head_del(it);
|
list_head_remove(it);
|
||||||
kfree(timer);
|
kfree(timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -479,7 +479,7 @@ void add_timer(struct timer_list *timer)
|
|||||||
#ifdef ENABLE_REAL_TIMER_SYSTEM
|
#ifdef ENABLE_REAL_TIMER_SYSTEM
|
||||||
__add_timer_tvec_base(base, timer);
|
__add_timer_tvec_base(base, timer);
|
||||||
#else
|
#else
|
||||||
list_head_add_tail(&timer->entry, &base->list);
|
list_head_insert_before(&timer->entry, &base->list);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -491,7 +491,7 @@ void del_timer(struct timer_list *timer)
|
|||||||
#ifdef ENABLE_REAL_TIMER_SYSTEM
|
#ifdef ENABLE_REAL_TIMER_SYSTEM
|
||||||
__rem_timer_tvec_base(base, timer);
|
__rem_timer_tvec_base(base, timer);
|
||||||
#else
|
#else
|
||||||
list_head_del(&timer->entry);
|
list_head_remove(&timer->entry);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ ndtree_node_t *ndtree_get_root(ndtree_t *tree)
|
|||||||
void ndtree_add_child_to_node(ndtree_t *tree, ndtree_node_t *parent, ndtree_node_t *child)
|
void ndtree_add_child_to_node(ndtree_t *tree, ndtree_node_t *parent, ndtree_node_t *child)
|
||||||
{
|
{
|
||||||
child->parent = parent;
|
child->parent = parent;
|
||||||
list_head_add(&child->siblings, &parent->children);
|
list_head_insert_after(&child->siblings, &parent->children);
|
||||||
++tree->size;
|
++tree->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,7 +172,7 @@ static void __ndtree_tree_dealloc_rec(ndtree_t *tree, ndtree_node_t *node, ndtre
|
|||||||
{
|
{
|
||||||
ndtree_node_t *entry = list_entry(it, ndtree_node_t, siblings);
|
ndtree_node_t *entry = list_entry(it, ndtree_node_t, siblings);
|
||||||
it_save = it->prev;
|
it_save = it->prev;
|
||||||
list_head_del(it);
|
list_head_remove(it);
|
||||||
it = it_save;
|
it = it_save;
|
||||||
__ndtree_tree_dealloc_rec(tree, entry, node_cb);
|
__ndtree_tree_dealloc_rec(tree, entry, node_cb);
|
||||||
}
|
}
|
||||||
@@ -249,7 +249,7 @@ int ndtree_tree_remove_node_with_cb(ndtree_t *tree, ndtree_node_t *node, ndtree_
|
|||||||
{
|
{
|
||||||
if (tree && node) {
|
if (tree && node) {
|
||||||
// Remove the node from the parent list.
|
// Remove the node from the parent list.
|
||||||
list_head_del(&node->siblings);
|
list_head_remove(&node->siblings);
|
||||||
// If the node has children, we need to migrate them.
|
// If the node has children, we need to migrate them.
|
||||||
if (!list_head_empty(&node->children)) {
|
if (!list_head_empty(&node->children)) {
|
||||||
// The new parent, by default it is NULL.
|
// The new parent, by default it is NULL.
|
||||||
@@ -269,7 +269,7 @@ int ndtree_tree_remove_node_with_cb(ndtree_t *tree, ndtree_node_t *node, ndtree_
|
|||||||
child->parent = new_parent;
|
child->parent = new_parent;
|
||||||
}
|
}
|
||||||
// Merge the lists.
|
// Merge the lists.
|
||||||
list_head_merge(new_list, &node->children);
|
list_head_append(new_list, &node->children);
|
||||||
}
|
}
|
||||||
if (node_cb)
|
if (node_cb)
|
||||||
node_cb(tree, node);
|
node_cb(tree, node);
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ block_found:
|
|||||||
page = list_entry(/* ... */, /* ... */, /* ... */);
|
page = list_entry(/* ... */, /* ... */, /* ... */);
|
||||||
|
|
||||||
// Remove the descriptor of its first page frame.
|
// Remove the descriptor of its first page frame.
|
||||||
list_head_del(&/* ... */);
|
list_head_remove(&/* ... */);
|
||||||
|
|
||||||
// Set the page as allocated, thus, remove the flag FREE_PAGE.
|
// Set the page as allocated, thus, remove the flag FREE_PAGE.
|
||||||
__bb_clear_flag(/* ... */, /* ... */);
|
__bb_clear_flag(/* ... */, /* ... */);
|
||||||
@@ -182,7 +182,7 @@ block_found:
|
|||||||
assert(/* ... */ &&!/* ... */);
|
assert(/* ... */ &&!/* ... */);
|
||||||
|
|
||||||
// Insert buddy as first element in the list of available blocks (free_list).
|
// Insert buddy as first element in the list of available blocks (free_list).
|
||||||
list_head_add(&/* ... */.siblings, &/* ... */);
|
list_head_insert_after(&/* ... */.siblings, &/* ... */);
|
||||||
|
|
||||||
// Increase the number of free block of the free_area_t.
|
// Increase the number of free block of the free_area_t.
|
||||||
/* ... */ += 1;
|
/* ... */ += 1;
|
||||||
@@ -277,7 +277,7 @@ void bb_free_pages(bb_instance_t *instance, bb_page_t *page)
|
|||||||
/* ... */;
|
/* ... */;
|
||||||
|
|
||||||
// Insert coalesced as first element in the free list.
|
// Insert coalesced as first element in the free list.
|
||||||
list_head_add(&/* ... */, &/* ... */);
|
list_head_insert_after(&/* ... */, &/* ... */);
|
||||||
|
|
||||||
// Increase the number of free block of the free_area_t.
|
// Increase the number of free block of the free_area_t.
|
||||||
/* ... */;
|
/* ... */;
|
||||||
@@ -342,7 +342,7 @@ void buddy_system_init(bb_instance_t *instance,
|
|||||||
// Set the page as root.
|
// Set the page as root.
|
||||||
__bb_set_flag(page, ROOT_PAGE);
|
__bb_set_flag(page, ROOT_PAGE);
|
||||||
// Insert the page inside the list of free pages of the area.
|
// Insert the page inside the list of free pages of the area.
|
||||||
list_head_add_tail(&page->location.siblings, &area->free_list);
|
list_head_insert_before(&page->location.siblings, &area->free_list);
|
||||||
// Increase the number of free block of the area.
|
// Increase the number of free block of the area.
|
||||||
area->nr_free++;
|
area->nr_free++;
|
||||||
// Move to the next page.
|
// Move to the next page.
|
||||||
@@ -388,7 +388,7 @@ static void __cache_extend(bb_instance_t *instance, int count)
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
bb_page_t *page = bb_alloc_pages(instance, 0);
|
bb_page_t *page = bb_alloc_pages(instance, 0);
|
||||||
list_head_add(&page->location.cache, &instance->free_pages_cache_list);
|
list_head_insert_after(&page->location.cache, &instance->free_pages_cache_list);
|
||||||
instance->free_pages_cache_size++;
|
instance->free_pages_cache_size++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -417,7 +417,7 @@ static bb_page_t *__cached_alloc(bb_instance_t *instance)
|
|||||||
|
|
||||||
static void __cached_free(bb_instance_t *instance, bb_page_t *page)
|
static void __cached_free(bb_instance_t *instance, bb_page_t *page)
|
||||||
{
|
{
|
||||||
list_head_add(&page->location.cache, &instance->free_pages_cache_list);
|
list_head_insert_after(&page->location.cache, &instance->free_pages_cache_list);
|
||||||
|
|
||||||
if (instance->free_pages_cache_size > HIGH_WATERMARK_LEVEL) {
|
if (instance->free_pages_cache_size > HIGH_WATERMARK_LEVEL) {
|
||||||
// Free pages to the buddy system
|
// Free pages to the buddy system
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ uint32_t create_vm_area(mm_struct_t *mm,
|
|||||||
new_segment->vm_mm = mm;
|
new_segment->vm_mm = mm;
|
||||||
|
|
||||||
// Update memory descriptor list of vm_area_struct.
|
// Update memory descriptor list of vm_area_struct.
|
||||||
list_head_add(&new_segment->vm_list, &mm->mmap_list);
|
list_head_insert_after(&new_segment->vm_list, &mm->mmap_list);
|
||||||
mm->mmap_cache = new_segment;
|
mm->mmap_cache = new_segment;
|
||||||
|
|
||||||
// Update memory descriptor info.
|
// Update memory descriptor info.
|
||||||
@@ -152,7 +152,7 @@ uint32_t clone_vm_area(mm_struct_t *mm, vm_area_struct_t *area, int cow, uint32_
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update memory descriptor list of vm_area_struct.
|
// Update memory descriptor list of vm_area_struct.
|
||||||
list_head_add(&new_segment->vm_list, &mm->mmap_list);
|
list_head_insert_after(&new_segment->vm_list, &mm->mmap_list);
|
||||||
mm->mmap_cache = new_segment;
|
mm->mmap_cache = new_segment;
|
||||||
|
|
||||||
// Update memory descriptor info.
|
// Update memory descriptor info.
|
||||||
@@ -607,7 +607,7 @@ void destroy_process_image(mm_struct_t *mm)
|
|||||||
|
|
||||||
// Delete segment from the mmap
|
// Delete segment from the mmap
|
||||||
it = segment->vm_list.next;
|
it = segment->vm_list.next;
|
||||||
list_head_del(&segment->vm_list);
|
list_head_remove(&segment->vm_list);
|
||||||
--mm->map_count;
|
--mm->map_count;
|
||||||
|
|
||||||
kmem_cache_free(segment);
|
kmem_cache_free(segment);
|
||||||
|
|||||||
+13
-13
@@ -71,11 +71,11 @@ static int __alloc_slab_page(kmem_cache_t *cachep, gfp_t flags)
|
|||||||
// Build the objects structures
|
// Build the objects structures
|
||||||
for (unsigned int i = 0; i < page->slab_objcnt; i++) {
|
for (unsigned int i = 0; i < page->slab_objcnt; i++) {
|
||||||
kmem_obj *obj = KMEM_OBJ(cachep, pg_addr + cachep->size * i);
|
kmem_obj *obj = KMEM_OBJ(cachep, pg_addr + cachep->size * i);
|
||||||
list_head_add(&obj->objlist, &page->slab_freelist);
|
list_head_insert_after(&obj->objlist, &page->slab_freelist);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the page to the slab list and update the counters
|
// Add the page to the slab list and update the counters
|
||||||
list_head_add(&page->slabs, &cachep->slabs_free);
|
list_head_insert_after(&page->slabs, &cachep->slabs_free);
|
||||||
cachep->total_num += page->slab_objcnt;
|
cachep->total_num += page->slab_objcnt;
|
||||||
cachep->free_num += page->slab_objcnt;
|
cachep->free_num += page->slab_objcnt;
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@ static void __kmem_cache_create(kmem_cache_t *cachep, const char *name, unsigned
|
|||||||
|
|
||||||
__kmem_cache_refill(cachep, start_count, flags);
|
__kmem_cache_refill(cachep, start_count, flags);
|
||||||
|
|
||||||
list_head_add(&cachep->cache_list, &kmem_caches_list);
|
list_head_insert_after(&cachep->cache_list, &kmem_caches_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void *__kmem_cache_alloc_slab(kmem_cache_t *cachep, page_t *slab_page)
|
static inline void *__kmem_cache_alloc_slab(kmem_cache_t *cachep, page_t *slab_page)
|
||||||
@@ -161,7 +161,7 @@ static inline void __kmem_cache_free_slab(kmem_cache_t *cachep, page_t *slab_pag
|
|||||||
cachep->free_num -= slab_page->slab_objfree;
|
cachep->free_num -= slab_page->slab_objfree;
|
||||||
cachep->total_num -= slab_page->slab_objcnt;
|
cachep->total_num -= slab_page->slab_objcnt;
|
||||||
// Clear objcnt, used as a flag to check if the page belongs to the slab
|
// Clear objcnt, used as a flag to check if the page belongs to the slab
|
||||||
slab_page->slab_objcnt = 0;
|
slab_page->slab_objcnt = 0;
|
||||||
slab_page->container.slab_main_page = NULL;
|
slab_page->container.slab_main_page = NULL;
|
||||||
|
|
||||||
// Reset all non-root slab pages
|
// Reset all non-root slab pages
|
||||||
@@ -225,7 +225,7 @@ void kmem_cache_destroy(kmem_cache_t *cachep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
kmem_cache_free(cachep);
|
kmem_cache_free(cachep);
|
||||||
list_head_del(&cachep->cache_list);
|
list_head_remove(&cachep->cache_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_CACHE_TRACE
|
#ifdef ENABLE_CACHE_TRACE
|
||||||
@@ -251,16 +251,16 @@ void *kmem_cache_alloc(kmem_cache_t *cachep, gfp_t flags)
|
|||||||
// Add a free slab to partial list because in any case an element will
|
// Add a free slab to partial list because in any case an element will
|
||||||
// be removed before the function returns
|
// be removed before the function returns
|
||||||
list_head *free_slab = list_head_pop(&cachep->slabs_free);
|
list_head *free_slab = list_head_pop(&cachep->slabs_free);
|
||||||
list_head_add(free_slab, &cachep->slabs_partial);
|
list_head_insert_after(free_slab, &cachep->slabs_partial);
|
||||||
}
|
}
|
||||||
|
|
||||||
page_t *slab_page = list_entry(list_head_front(&cachep->slabs_partial), page_t, slabs);
|
page_t *slab_page = list_entry(cachep->slabs_partial.next, page_t, slabs);
|
||||||
void *ptr = __kmem_cache_alloc_slab(cachep, slab_page);
|
void *ptr = __kmem_cache_alloc_slab(cachep, slab_page);
|
||||||
|
|
||||||
// If the slab is now full, add it to the full slabs list
|
// If the slab is now full, add it to the full slabs list
|
||||||
if (slab_page->slab_objfree == 0) {
|
if (slab_page->slab_objfree == 0) {
|
||||||
list_head *slab_full_elem = list_head_pop(&cachep->slabs_partial);
|
list_head *slab_full_elem = list_head_pop(&cachep->slabs_partial);
|
||||||
list_head_add(slab_full_elem, &cachep->slabs_full);
|
list_head_insert_after(slab_full_elem, &cachep->slabs_full);
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_CACHE_TRACE
|
#ifdef ENABLE_CACHE_TRACE
|
||||||
pr_notice("CHACE-ALLOC 0x%p in %-20s at %s:%d\n", ptr, cachep->name, file, line);
|
pr_notice("CHACE-ALLOC 0x%p in %-20s at %s:%d\n", ptr, cachep->name, file, line);
|
||||||
@@ -292,23 +292,23 @@ void kmem_cache_free(void *ptr)
|
|||||||
kmem_obj *obj = KMEM_OBJ(cachep, ptr);
|
kmem_obj *obj = KMEM_OBJ(cachep, ptr);
|
||||||
|
|
||||||
// Add object to the free list
|
// Add object to the free list
|
||||||
list_head_add(&obj->objlist, &slab_page->slab_freelist);
|
list_head_insert_after(&obj->objlist, &slab_page->slab_freelist);
|
||||||
slab_page->slab_objfree++;
|
slab_page->slab_objfree++;
|
||||||
cachep->free_num++;
|
cachep->free_num++;
|
||||||
|
|
||||||
// Now page is completely free
|
// Now page is completely free
|
||||||
if (slab_page->slab_objfree == slab_page->slab_objcnt) {
|
if (slab_page->slab_objfree == slab_page->slab_objcnt) {
|
||||||
// Remove page from partial list
|
// Remove page from partial list
|
||||||
list_head_del(&slab_page->slabs);
|
list_head_remove(&slab_page->slabs);
|
||||||
// Add page to free list
|
// Add page to free list
|
||||||
list_head_add(&slab_page->slabs, &cachep->slabs_free);
|
list_head_insert_after(&slab_page->slabs, &cachep->slabs_free);
|
||||||
}
|
}
|
||||||
// Now page is not full, so change its list
|
// Now page is not full, so change its list
|
||||||
else if (slab_page->slab_objfree == 1) {
|
else if (slab_page->slab_objfree == 1) {
|
||||||
// Remove page from full list
|
// Remove page from full list
|
||||||
list_head_del(&slab_page->slabs);
|
list_head_remove(&slab_page->slabs);
|
||||||
// Add page to partial list
|
// Add page to partial list
|
||||||
list_head_add(&slab_page->slabs, &cachep->slabs_partial);
|
list_head_insert_after(&slab_page->slabs, &cachep->slabs_partial);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ static inline task_struct *__alloc_task(task_struct *source, task_struct *parent
|
|||||||
// If we have a parent, set the sibling child relation.
|
// If we have a parent, set the sibling child relation.
|
||||||
if (parent) {
|
if (parent) {
|
||||||
// Set the new_process as child of current.
|
// Set the new_process as child of current.
|
||||||
list_head_add_tail(&proc->sibling, &parent->children);
|
list_head_insert_before(&proc->sibling, &parent->children);
|
||||||
}
|
}
|
||||||
if (source)
|
if (source)
|
||||||
memcpy(&proc->thread, &source->thread, sizeof(thread_struct_t));
|
memcpy(&proc->thread, &source->thread, sizeof(thread_struct_t));
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ void scheduler_enqueue_task(task_struct *process)
|
|||||||
runqueue.curr = process;
|
runqueue.curr = process;
|
||||||
}
|
}
|
||||||
// Add the new process at the end.
|
// Add the new process at the end.
|
||||||
list_head_add_tail(&process->run_list, &runqueue.queue);
|
list_head_insert_before(&process->run_list, &runqueue.queue);
|
||||||
// Increment the number of active processes.
|
// Increment the number of active processes.
|
||||||
++runqueue.num_active;
|
++runqueue.num_active;
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@ void scheduler_enqueue_task(task_struct *process)
|
|||||||
void scheduler_dequeue_task(task_struct *process)
|
void scheduler_dequeue_task(task_struct *process)
|
||||||
{
|
{
|
||||||
// Delete the process from the list of running processes.
|
// Delete the process from the list of running processes.
|
||||||
list_head_del(&process->run_list);
|
list_head_remove(&process->run_list);
|
||||||
// Decrement the number of active processes.
|
// Decrement the number of active processes.
|
||||||
--runqueue.num_active;
|
--runqueue.num_active;
|
||||||
if (process->se.is_periodic)
|
if (process->se.is_periodic)
|
||||||
@@ -484,7 +484,7 @@ pid_t sys_waitpid(pid_t pid, int *status, int options)
|
|||||||
// Finalize the VFS structures.
|
// Finalize the VFS structures.
|
||||||
vfs_destroy_task(entry);
|
vfs_destroy_task(entry);
|
||||||
// Remove entry from children of parent.
|
// Remove entry from children of parent.
|
||||||
list_head_del(&entry->sibling);
|
list_head_remove(&entry->sibling);
|
||||||
// Remove entry from the scheduling queue.
|
// Remove entry from the scheduling queue.
|
||||||
scheduler_dequeue_task(entry);
|
scheduler_dequeue_task(entry);
|
||||||
// Delete the task_struct.
|
// Delete the task_struct.
|
||||||
@@ -535,7 +535,7 @@ void sys_exit(int exit_code)
|
|||||||
}
|
}
|
||||||
pr_debug("}\n");
|
pr_debug("}\n");
|
||||||
// Plug the list of children.
|
// Plug the list of children.
|
||||||
list_head_merge(&init_proc->children, &runqueue.curr->children);
|
list_head_append(&init_proc->children, &runqueue.curr->children);
|
||||||
// Print the list of children.
|
// Print the list of children.
|
||||||
pr_debug("New list of init children (%d): {\n", init_proc->pid);
|
pr_debug("New list of init children (%d): {\n", init_proc->pid);
|
||||||
list_for_each_decl(it, &init_proc->children)
|
list_for_each_decl(it, &init_proc->children)
|
||||||
|
|||||||
@@ -22,78 +22,78 @@
|
|||||||
/// @param task the task to update.
|
/// @param task the task to update.
|
||||||
static void __update_task_statistics(task_struct *task);
|
static void __update_task_statistics(task_struct *task);
|
||||||
|
|
||||||
|
/// @brief Checks if the given task is actually a periodic task.
|
||||||
|
/// @param task the task to check.
|
||||||
|
/// @return true if the task is periodic, false otherwise.
|
||||||
|
static inline bool_t __is_periodic_task(task_struct *task)
|
||||||
|
{
|
||||||
|
// Check if the task is a periodic one and it is not under analysis.
|
||||||
|
return task->se.is_periodic && !task->se.is_under_analysis;
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Employs time-sharing, giving each job a timeslice, and is also
|
/// @brief Employs time-sharing, giving each job a timeslice, and is also
|
||||||
/// preemptive since the scheduler forces the task out of the CPU once
|
/// preemptive since the scheduler forces the task out of the CPU once
|
||||||
/// the timeslice expires.
|
/// the timeslice expires.
|
||||||
/// @param runqueue list of all processes.
|
/// @param runqueue list of all processes.
|
||||||
/// @param skip_periodic tells the algorithm if there are periodic processes
|
/// @param skip_periodic tells the algorithm if there are periodic processes in
|
||||||
/// in the list, and in that case it needs to skip them.
|
/// the list, and in that case it needs to skip them.
|
||||||
/// @return the next task on success, NULL on failure.
|
/// @return the next task on success, NULL on failure.
|
||||||
static inline task_struct *__scheduler_rr(runqueue_t *runqueue, bool_t skip_periodic)
|
static inline task_struct *__scheduler_rr(runqueue_t *runqueue, bool_t skip_periodic)
|
||||||
{
|
{
|
||||||
// If there is just one task, return it.
|
// If there is just one task, return it; no need to do anything.
|
||||||
if ((runqueue->curr->run_list.next == &runqueue->queue) &&
|
if (list_head_size(&runqueue->curr->run_list) <= 1) {
|
||||||
(runqueue->curr->run_list.prev == &runqueue->queue)) {
|
|
||||||
return runqueue->curr;
|
return runqueue->curr;
|
||||||
}
|
}
|
||||||
// By default, the next task is the current one.
|
// Search for the next task (we do not start from the head, so INSIDE, skip the head).
|
||||||
task_struct *next = NULL, *entry = NULL;
|
|
||||||
// Search for the next task (BEWARE: We do not start from the head, so INSIDE skip the head).
|
|
||||||
list_for_each_decl(it, &runqueue->curr->run_list)
|
list_for_each_decl(it, &runqueue->curr->run_list)
|
||||||
{
|
{
|
||||||
// Check if we reached the head of list_head, and skip it.
|
// Check if we reached the head of list_head, and skip it.
|
||||||
if (it == &runqueue->queue)
|
if (it == &runqueue->queue)
|
||||||
continue;
|
continue;
|
||||||
// Get the current entry.
|
// Get the current entry.
|
||||||
entry = list_entry(it, task_struct, run_list);
|
task_struct *entry = list_entry(it, task_struct, run_list);
|
||||||
|
|
||||||
// We consider only runnable processes
|
// We consider only runnable processes
|
||||||
if (entry->state != TASK_RUNNING)
|
if (entry->state != TASK_RUNNING)
|
||||||
continue;
|
continue;
|
||||||
|
// If entry is a periodic task, and we were asked to skip periodic tasks, skip it.
|
||||||
// Skip the task if it is a periodic one, we are issued to skip
|
if (__is_periodic_task(entry) && skip_periodic)
|
||||||
// periodic tasks, and the entry is not a periodic task under
|
|
||||||
// analysis.
|
|
||||||
if (entry->se.is_periodic && skip_periodic && !entry->se.is_under_analysis)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// We have our next entry.
|
// We have our next entry.
|
||||||
next = entry;
|
return entry;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return next;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Is a non-preemptive algorithm, where each task is assigned a
|
/// @brief Is a non-preemptive algorithm, where each task is assigned a
|
||||||
/// priority. Processes with highest priority are executed first, while
|
/// priority. Processes with highest priority are executed first, while
|
||||||
/// processes with same priority are executed on first-come/first-served
|
/// processes with same priority are executed on first-come/first-served basis.
|
||||||
/// basis. Priority can be decided based on memory requirements, time
|
/// Priority can be decided based on memory requirements, time requirements or
|
||||||
/// requirements or any other resource requirement.
|
/// any other resource requirement.
|
||||||
/// @param runqueue list of all processes.
|
/// @param runqueue list of all processes.
|
||||||
/// @param skip_periodic tells the algorithm if there are periodic processes
|
/// @param skip_periodic tells the algorithm if there are periodic processes in
|
||||||
/// in the list, and in that case it needs to skip them.
|
/// the list, and in that case it needs to skip them.
|
||||||
/// @return the next task on success, NULL on failure.
|
/// @return the next task on success, NULL on failure.
|
||||||
static inline task_struct *__scheduler_priority(runqueue_t *runqueue, bool_t skip_periodic)
|
static inline task_struct *__scheduler_priority(runqueue_t *runqueue, bool_t skip_periodic)
|
||||||
{
|
{
|
||||||
return __scheduler_rr(runqueue, skip_periodic);
|
return __scheduler_rr(runqueue, skip_periodic);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief It aims at giving a fair share of CPU time to processes, and
|
/// @brief It aims at giving a fair share of CPU time to processes, and achieves
|
||||||
/// achieves that by associating a virtual runtime to each of them. It always
|
/// that by associating a virtual runtime to each of them. It always tries to
|
||||||
/// tries to run the task with the smallest vruntime (i.e., the task which
|
/// run the task with the smallest vruntime (i.e., the task which executed least
|
||||||
/// executed least so far). It always tries to split up CPU time between
|
/// so far). It always tries to split up CPU time between runnable tasks as
|
||||||
/// runnable tasks as close to "ideal multitasking hardware" as possible.
|
/// close to "ideal multitasking hardware" as possible.
|
||||||
/// @param runqueue list of all processes.
|
/// @param runqueue list of all processes.
|
||||||
/// @param skip_periodic tells the algorithm if there are periodic processes
|
/// @param skip_periodic tells the algorithm if there are periodic processes in
|
||||||
/// in the list, and in that case it needs to skip them.
|
/// the list, and in that case it needs to skip them.
|
||||||
/// @return the next task on success, NULL on failure.
|
/// @return the next task on success, NULL on failure.
|
||||||
static inline task_struct *__scheduler_cfs(runqueue_t *runqueue, bool_t skip_periodic)
|
static inline task_struct *__scheduler_cfs(runqueue_t *runqueue, bool_t skip_periodic)
|
||||||
{
|
{
|
||||||
return __scheduler_rr(runqueue, skip_periodic);
|
return __scheduler_rr(runqueue, skip_periodic);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Executes the task with the earliest absolute deadline among all
|
/// @brief Executes the task with the earliest absolute deadline among all the
|
||||||
/// the ready tasks.
|
/// ready tasks.
|
||||||
/// @param runqueue list of all processes.
|
/// @param runqueue list of all processes.
|
||||||
/// @return the next task on success, NULL on failure.
|
/// @return the next task on success, NULL on failure.
|
||||||
static inline task_struct *__scheduler_aedf(runqueue_t *runqueue)
|
static inline task_struct *__scheduler_aedf(runqueue_t *runqueue)
|
||||||
@@ -101,10 +101,10 @@ static inline task_struct *__scheduler_aedf(runqueue_t *runqueue)
|
|||||||
return __scheduler_rr(runqueue, false);
|
return __scheduler_rr(runqueue, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Executes the task with the earliest absolute DEADLINE among all
|
/// @brief Executes the task with the earliest absolute DEADLINE among all the
|
||||||
/// the ready tasks. When a task was executed, and its period is starting
|
/// ready tasks. When a task was executed, and its period is starting again, it
|
||||||
/// again, it must be set as 'executable again', and its deadline and next_period
|
/// must be set as 'executable again', and its deadline and next_period must be
|
||||||
/// must be updated.
|
/// updated.
|
||||||
/// @param runqueue list of all processes.
|
/// @param runqueue list of all processes.
|
||||||
/// @return the next task on success, NULL on failure.
|
/// @return the next task on success, NULL on failure.
|
||||||
static inline task_struct *__scheduler_edf(runqueue_t *runqueue)
|
static inline task_struct *__scheduler_edf(runqueue_t *runqueue)
|
||||||
@@ -112,11 +112,11 @@ static inline task_struct *__scheduler_edf(runqueue_t *runqueue)
|
|||||||
return __scheduler_rr(runqueue, false);
|
return __scheduler_rr(runqueue, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Executes the task with the earliest next PERIOD among all the
|
/// @brief Executes the task with the earliest next PERIOD among all the ready
|
||||||
/// ready tasks.
|
/// tasks.
|
||||||
/// @details When a task was executed, and its period is starting again, it
|
/// @details When a task was executed, and its period is starting again, it must
|
||||||
/// must be set as 'executable again', and its deadline and next_period must
|
/// be set as 'executable again', and its deadline and next_period must be
|
||||||
/// be updated.
|
/// updated.
|
||||||
/// @param runqueue list of all processes.
|
/// @param runqueue list of all processes.
|
||||||
/// @return the next task on success, NULL on failure.
|
/// @return the next task on success, NULL on failure.
|
||||||
static inline task_struct *__scheduler_rm(runqueue_t *runqueue)
|
static inline task_struct *__scheduler_rm(runqueue_t *runqueue)
|
||||||
|
|||||||
@@ -14,12 +14,12 @@
|
|||||||
|
|
||||||
static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_entry_t *wq)
|
static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_entry_t *wq)
|
||||||
{
|
{
|
||||||
list_head_add_tail(&wq->task_list, &head->task_list);
|
list_head_insert_before(&wq->task_list, &head->task_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void __remove_wait_queue(wait_queue_head_t *head, wait_queue_entry_t *wq)
|
static inline void __remove_wait_queue(wait_queue_head_t *head, wait_queue_entry_t *wq)
|
||||||
{
|
{
|
||||||
list_head_del(&wq->task_list);
|
list_head_remove(&wq->task_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_waitqueue_entry(wait_queue_entry_t *wq, struct task_struct *task)
|
void init_waitqueue_entry(wait_queue_entry_t *wq, struct task_struct *task)
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ static int __send_signal(int sig, siginfo_t *info, struct task_struct *t)
|
|||||||
__unlock_task_sighand(t);
|
__unlock_task_sighand(t);
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
list_head_add_tail(&q->list, &t->pending.list);
|
list_head_insert_before(&q->list, &t->pending.list);
|
||||||
if (info != SEND_SIG_NOINFO)
|
if (info != SEND_SIG_NOINFO)
|
||||||
memcpy(&q->info, info, sizeof(siginfo_t));
|
memcpy(&q->info, info, sizeof(siginfo_t));
|
||||||
// Set that there is a signal pending.
|
// Set that there is a signal pending.
|
||||||
@@ -219,7 +219,7 @@ static inline void __collect_signal(int sig, sigpending_t *list, siginfo_t *info
|
|||||||
if (queue_entry) {
|
if (queue_entry) {
|
||||||
pr_debug("__collect_signal(%d, %p, %p) : Remove and delete sigqueue entry : %p.\n", sig, list, info, queue_entry);
|
pr_debug("__collect_signal(%d, %p, %p) : Remove and delete sigqueue entry : %p.\n", sig, list, info, queue_entry);
|
||||||
// Remove the entry from the queue.
|
// Remove the entry from the queue.
|
||||||
list_head_del(&queue_entry->list);
|
list_head_remove(&queue_entry->list);
|
||||||
// Copy the details about the entry inside the info structure.
|
// Copy the details about the entry inside the info structure.
|
||||||
__copy_siginfo(info, &queue_entry->info);
|
__copy_siginfo(info, &queue_entry->info);
|
||||||
// Free the memory for the queue entry.
|
// Free the memory for the queue entry.
|
||||||
@@ -346,7 +346,7 @@ static void __rm_from_queue(sigset_t *mask, sigpending_t *q)
|
|||||||
int sig = entry->info.si_signo;
|
int sig = entry->info.si_signo;
|
||||||
|
|
||||||
if (sigismember(mask, sig)) {
|
if (sigismember(mask, sig)) {
|
||||||
list_head_del(it);
|
list_head_remove(it);
|
||||||
kfree(entry);
|
kfree(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -205,6 +205,8 @@ int main(int argc, char **argv)
|
|||||||
// Set the user id.
|
// Set the user id.
|
||||||
setuid(pwd->pw_uid);
|
setuid(pwd->pw_uid);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
// Print /etc/motd if it exists.
|
// Print /etc/motd if it exists.
|
||||||
__print_message_file("/etc/motd");
|
__print_message_file("/etc/motd");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user