Skip to content

Commit

Permalink
- Populate metadata ahead of view in a thread.
Browse files Browse the repository at this point in the history
  • Loading branch information
Extrems committed Feb 10, 2024
1 parent 83ed4b7 commit f5b7a28
Show file tree
Hide file tree
Showing 7 changed files with 214 additions and 34 deletions.
2 changes: 2 additions & 0 deletions cube/swiss/source/devices/deviceHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ typedef struct {
file_meta *meta;
u8 other[128]; // Store anything else we want here
void* uiObj; // UI associated with this file_handle
vu32 lockCount;
lwp_t thread;
} file_handle; // Note: If the contents of this change, recompile pc/usbgecko/main.c

typedef struct {
Expand Down
77 changes: 77 additions & 0 deletions cube/swiss/source/devices/filelock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2024, Extrems <extrems@extremscorner.org>
*
* This file is part of Swiss.
*
* Swiss is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Swiss is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* with Swiss. If not, see <https://www.gnu.org/licenses/>.
*/

#include <ogc/lwp.h>
#include <ogc/machine/processor.h>
#include <stdbool.h>
#include <stdint.h>
#include "deviceHandler.h"

static lwpq_t queue = LWP_TQUEUE_NULL;

__attribute((constructor))
static void initQueue(void)
{
LWP_InitQueue(&queue);
}

void lockFile(file_handle *file)
{
uint32_t level;

_CPU_ISR_Disable(level);

while (file->lockCount != 0 && file->thread != LWP_GetSelf())
LWP_ThreadSleep(queue);

file->lockCount++;
file->thread = LWP_GetSelf();

_CPU_ISR_Restore(level);
}

bool trylockFile(file_handle *file)
{
uint32_t level;

_CPU_ISR_Disable(level);

if (file->lockCount != 0 && file->thread != LWP_GetSelf()) {
_CPU_ISR_Restore(level);
return false;
}

file->lockCount++;
file->thread = LWP_GetSelf();

_CPU_ISR_Restore(level);
return true;
}

void unlockFile(file_handle *file)
{
uint32_t level;

_CPU_ISR_Disable(level);

if (--file->lockCount == 0)
LWP_ThreadBroadcast(queue);

_CPU_ISR_Restore(level);
}
30 changes: 30 additions & 0 deletions cube/swiss/source/devices/filelock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2024, Extrems <extrems@extremscorner.org>
*
* This file is part of Swiss.
*
* Swiss is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Swiss is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* with Swiss. If not, see <https://www.gnu.org/licenses/>.
*/

#ifndef __FILELOCK_H__
#define __FILELOCK_H__

#include <stdbool.h>
#include "deviceHandler.h"

void lockFile(file_handle *file);
bool trylockFile(file_handle *file);
void unlockFile(file_handle *file);

#endif /* __FILELOCK_H__ */
27 changes: 26 additions & 1 deletion cube/swiss/source/devices/filemeta.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <main.h>
#include <ogc/lwp_heap.h>
#include "dvd.h"
#include "filelock.h"
#include "filemeta.h"
#include "nkit.h"
#include "swiss.h"
Expand All @@ -29,6 +30,7 @@ extern BNR blankbanner;
#define META_CACHE_SIZE (sizeof(file_meta) * NUM_META_MAX)

static heap_cntrl* meta_cache = NULL;
static lwp_t meta_thread = LWP_THREAD_NULL;

void meta_free(file_meta* meta) {
if(meta_cache && meta) {
Expand All @@ -53,9 +55,10 @@ file_meta* meta_alloc() {
int i = 0;
for (i = 0; i < getCurrentDirEntryCount(); i++) {
if(!in_range(i, current_view_start, current_view_end)) {
if(dirEntries[i].meta) {
if(dirEntries[i].meta && trylockFile(&dirEntries[i])) {
meta_free(dirEntries[i].meta);
dirEntries[i].meta = NULL;
unlockFile(&dirEntries[i]);
break;
}
}
Expand Down Expand Up @@ -391,3 +394,25 @@ file_handle* meta_find_disc2(file_handle *f) {
}
return disc2File;
}

static void *meta_thread_func(void *arg) {
file_handle* dirEntries = getCurrentDirEntries();
for(int i = 0; i < getCurrentDirEntryCount(); i++) {
if(meta_thread != LWP_GetSelf()) break;
if(trylockFile(&dirEntries[i])) {
populate_meta(&dirEntries[i]);
unlockFile(&dirEntries[i]);
}
}
return NULL;
}

void meta_thread_start() {
LWP_CreateThread(&meta_thread, meta_thread_func, NULL, NULL, 0, LWP_PRIO_NORMAL);
}

void meta_thread_stop() {
lwp_t thread = meta_thread;
meta_thread = LWP_THREAD_NULL;
LWP_JoinThread(thread, NULL);
}
2 changes: 2 additions & 0 deletions cube/swiss/source/devices/filemeta.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
void populate_meta(file_handle *f);
void repopulate_meta(file_handle *f);
file_handle* meta_find_disc2(file_handle *f);
void meta_thread_start();
void meta_thread_stop();
void meta_free(file_meta* meta);
#endif

4 changes: 2 additions & 2 deletions cube/swiss/source/devices/usbgecko/usbgecko.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,13 @@ file_handle* usbgecko_get_entry() {
// Try get a reply
usb_recvbuffer_safe(1, get_buffer(), 1);
if(get_buffer()[0] == ANS_READY) {
usb_recvbuffer_safe(1, get_buffer(), sizeof(file_handle));
usb_recvbuffer_safe(1, get_buffer(), offsetof(file_handle, lockCount));
if(!get_buffer()[0]) {
return NULL;
}
else {
memset(&filehndl, 0, sizeof(file_handle));
memcpy(&filehndl, get_buffer(), sizeof(file_handle));
memcpy(&filehndl, get_buffer(), offsetof(file_handle, lockCount));
filehndl.size = bswap32(filehndl.size);
filehndl.fileAttrib = bswap32(filehndl.fileAttrib);
return &filehndl;
Expand Down

0 comments on commit f5b7a28

Please sign in to comment.