Skip to content

Commit

Permalink
o Rewrote portions of syslog() handling
Browse files Browse the repository at this point in the history
o Added syscall 422 (sys_futex_time64)
o Other tweaks
  • Loading branch information
Mike Miller committed Jan 4, 2024
1 parent acf9afa commit b86ad3f
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 137 deletions.
4 changes: 2 additions & 2 deletions debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
#include <stdio.h>
#include <stdlib.h>

#define WAIT_SLEEP 200 // Was 25 for a long time. -mke
#define WAIT_MAX_UPPER 55500
#define WAIT_SLEEP 2500 // Was 25 for a long time. -mke
#define WAIT_MAX_UPPER 555000

void ish_printk(const char *msg, ...);
void ish_vprintk(const char *msg, va_list args);
Expand Down
3 changes: 2 additions & 1 deletion fs/poll.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,8 @@ void poll_destroy(struct poll *poll) {
free(poll_fd);
}

while(task_ref_cnt_get(current, 0) > 1) {
while(task_ref_cnt_get(current, 0) > 2) {
struct task* foo = current;
nanosleep(&lock_pause, NULL);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,4 @@
uuid = "6E8E3717-3660-4400-9A7C-07FA89334909"
type = "4"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.SymbolicBreakpoint">
<BreakpointContent
uuid = "035095F5-47C6-49AD-8C66-AFEF7229BBBE"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "Yes"
symbolName = "UIApplicationMain"
moduleName = "UIKitCore">
<Actions>
<BreakpointActionProxy
ActionExtensionID = "Xcode.BreakpointAction.DebuggerCommand">
<ActionContent
consoleCommand = "process handle SIGUSR1 SIGPIPE -n true -p true -s false">
</ActionContent>
</BreakpointActionProxy>
</Actions>
<Locations>
<Location
uuid = "035095F5-47C6-49AD-8C66-AFEF7229BBBE - dc2f8c5e001177f0"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "UIApplicationMain"
moduleName = "UIKitCore"
usesParentBreakpointCondition = "Yes"
offsetFromSymbolStart = "0">
</Location>
<Location
uuid = "035095F5-47C6-49AD-8C66-AFEF7229BBBE - ed0225d50b1c0976"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "UIKit.UIApplicationMain(Swift.Int32, Swift.Optional&lt;Swift.UnsafeMutablePointer&lt;Swift.UnsafeMutablePointer&lt;Swift.Int8&gt;&gt;&gt;, Swift.Optional&lt;Swift.String&gt;, Swift.Optional&lt;Swift.String&gt;) -&gt; Swift.Int32"
moduleName = "UIKitCore"
usesParentBreakpointCondition = "Yes"
offsetFromSymbolStart = "0">
</Location>
</Locations>
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>
3 changes: 3 additions & 0 deletions kernel/calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

extern bool isGlibC;

extern dword_t sys_futex_time64(addr_t uaddr, dword_t op, dword_t val, addr_t timeout_or_val2, addr_t uaddr2, dword_t val3);

dword_t syscall_stub(void) {
STRACE("syscall_stub()");
// I should probably do a prink here. Not sure why I removed it
Expand Down Expand Up @@ -276,6 +278,7 @@ syscall_t syscall_table[] = {
[407] = (syscall_t) sys_clock_nanosleep_time64, // clock_nanosleep_time64
[412] = (syscall_t) sys_utimensat64, // utimensat_time64
[414] = (syscall_t) sys_ppoll_time64,
[422] = (syscall_t) sys_futex_time64,
[424] = (syscall_t) syscall_stub, // pidfd_send_signal?
[436] = (syscall_t) syscall_stub,
[439] = (syscall_t) sys_faccessat, // faccessat2
Expand Down
34 changes: 34 additions & 0 deletions kernel/futex.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ static int futex_load(struct futex *futex, dword_t *out) {
return 0;
}



static int futex_wait(addr_t uaddr, dword_t val, struct timespec *timeout) {
struct futex *futex = futex_get(uaddr);
int err = 0;
Expand All @@ -148,6 +150,38 @@ static int futex_wait(addr_t uaddr, dword_t val, struct timespec *timeout) {
return err;
}

static int futex_wait_time64(addr_t uaddr, dword_t val, struct timespec64 *timeout64) {
// Convert struct timespec64 to struct timespec if needed
struct timespec timeout;
timeout.tv_sec = (time_t)timeout64->tv_sec;
timeout.tv_nsec = (long)timeout64->tv_nsec;

// Call the existing futex_wait with the converted timespec
return futex_wait(uaddr, val, &timeout);
}

dword_t sys_futex_time64(addr_t uaddr, dword_t op, dword_t val, addr_t timeout_or_val2, addr_t uaddr2, dword_t val3) {
if (!(op & FUTEX_PRIVATE_FLAG_)) {
STRACE("!FUTEX_PRIVATE ");
}

// Check for FUTEX_WAIT_BITSET operation
if ((op & FUTEX_CMD_MASK_) == FUTEX_WAIT_BITSET_) {
STRACE("futex(FUTEX_WAIT_BITSET_TIME64, %#x, %d, 0x%x) = ...\n", uaddr, val, timeout_or_val2);

// Get the timespec64 from user space
struct timespec64 timeout64;
if (user_get(timeout_or_val2, timeout64))
return _EFAULT;

// Call the futex_wait_time64 function
return futex_wait_time64(uaddr, val, &timeout64);
}

// Handle other futex operations (possibly by calling sys_futex)
return sys_futex(uaddr, op, val, timeout_or_val2, uaddr2, val3);
}

static int futex_wakelike(int op, addr_t uaddr, dword_t wake_max, dword_t requeue_max, addr_t requeue_addr) {
struct futex *futex = futex_get(uaddr);

Expand Down
95 changes: 41 additions & 54 deletions kernel/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,81 +30,67 @@ static lock_t log_lock = LOCK_INITIALIZER;
#define SYSLOG_ACTION_SIZE_UNREAD_ 9
#define SYSLOG_ACTION_SIZE_BUFFER_ 10

static size_t syslog_read(addr_t buf_addr, size_t len, int flags) {
if (len < 0)
static size_t syslog_read(addr_t buf_addr, size_t len, int flags, char* buffer, size_t buffer_size) {
if (len == 0 || buffer_size == 0)
return _EINVAL;
if (flags & FIFO_LAST) {
if ((size_t) len > log_max_since_clear)
len = log_max_since_clear;
} else {
if ((size_t) len > fifo_capacity(&log_buf))
len = fifo_capacity(&log_buf);
}
char *buf = malloc(len + 1);
fifo_read(&log_buf, buf, len, flags);

// Here we will split on \n and do one entry per line
// Keep printing tokens while one of the
// delimiters present
addr_t pointer = buf_addr; // Where we are in the buffer
char *token = strtok(buf, "\n"); // Get the first line

if(user_write(pointer, "\n", 1)) { // Positive return value = fail
free(buf);
return _EFAULT;
}

pointer++;


// Limit the read length to the size of the passed buffer
if (len > buffer_size - 1)
len = buffer_size - 1;

// Read from the log buffer
size_t read_len = fifo_read(&log_buf, buffer, len, flags);
buffer[read_len] = '\0'; // Ensure null-termination

// Write line by line to the user space, splitting on '\n'
addr_t pointer = buf_addr;
char *token = strtok(buffer, "\n");
while (token != NULL) {
size_t length = strlen(token);
if(user_write(pointer, token, length)) { // Positive return value = fail
free(buf);
if (user_write(pointer, token, length)) // Check for write failure
return _EFAULT;
}

pointer += length;

if(user_write(pointer, "\n", 1)) { // Positive return value = fail
free(buf);

if (user_write(pointer, "\n", 1)) // Check for write failure
return _EFAULT;
}

pointer++;
if(pointer < (buf_addr + (len -1))) {
token = strtok(NULL, "\n"); // Grab next token, deal with when back at top of while loop. -mke
} else {
token = NULL;
}

if (pointer < (buf_addr + len - 1))
token = strtok(NULL, "\n");
else
break; // Reached the end of the buffer
}

free(buf);

return len;
return pointer - buf_addr; // Return the number of bytes written
}

static size_t do_syslog(int type, addr_t buf_addr, int_t len) {
int res;
// Define a buffer size based on your requirements
const size_t BUFFER_SIZE = 8192;
char buffer[BUFFER_SIZE];

switch (type) {
case SYSLOG_ACTION_READ_:
return syslog_read(buf_addr, len, 0);
return syslog_read(buf_addr, len, 0, buffer, BUFFER_SIZE);
case SYSLOG_ACTION_READ_ALL_:
return syslog_read(buf_addr, len, FIFO_LAST | FIFO_PEEK);

case SYSLOG_ACTION_READ_CLEAR_:
res = (int)syslog_read(buf_addr, len, FIFO_LAST | FIFO_PEEK);
if (res < 0)
return res;
fallthrough;
return syslog_read(buf_addr, len, FIFO_LAST | FIFO_PEEK, buffer, BUFFER_SIZE);

case SYSLOG_ACTION_READ_CLEAR_: {
size_t res = syslog_read(buf_addr, len, FIFO_LAST | FIFO_PEEK, buffer, BUFFER_SIZE);
if (res < 0)
return res;
// fall through to clear
}
case SYSLOG_ACTION_CLEAR_:
log_max_since_clear = 0;
return 0;

case SYSLOG_ACTION_SIZE_UNREAD_:
return (int)fifo_size(&log_buf);
return fifo_size(&log_buf);
case SYSLOG_ACTION_SIZE_BUFFER_:
return (int)fifo_capacity(&log_buf);
return fifo_capacity(&log_buf);

// Other actions remain unchanged
case SYSLOG_ACTION_CLOSE_:
case SYSLOG_ACTION_OPEN_:
case SYSLOG_ACTION_CONSOLE_OFF_:
Expand All @@ -115,6 +101,7 @@ static size_t do_syslog(int type, addr_t buf_addr, int_t len) {
return _EINVAL;
}
}

size_t sys_syslog(int_t type, addr_t buf_addr, int_t len) {
lock(&log_lock, 0);
size_t retval = do_syslog(type, buf_addr, len);
Expand Down Expand Up @@ -202,7 +189,7 @@ _Noreturn void die(const char *msg, ...);
void die(const char *msg, ...) {
va_list args;
va_start(args, msg);
char buf[4096];
char buf[8192];
vsprintf(buf, msg, args);
die_handler(buf);
abort();
Expand Down
6 changes: 4 additions & 2 deletions kernel/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,10 @@ dword_t get_count_of_blocked_tasks(void) {
struct pid *pid_entry;
complex_lockt(&pids_lock, 0);
list_for_each_entry(&alive_pids_list, pid_entry, alive) {
if (pid_entry->task->io_block) {
res++;
if(pid_entry->task != NULL) {
if (pid_entry->task->io_block) {
res++;
}
}
}
// task_ref_cnt_mod(current, -1);
Expand Down
2 changes: 1 addition & 1 deletion main.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ int main(int argc, char *const argv[]) {
sa.sa_flags = SA_SIGINFO;

if(sigaction(/*SIGBUS*/SIGSEGV, &sa, NULL) == -1) {
printf("sigaction fails.\n");
printk("sigaction fails.\n");
return 0;
}

Expand Down
49 changes: 15 additions & 34 deletions util/sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,54 +59,30 @@ int wait_for_ignore_signals(cond_t *cond, lock_t *lock, struct timespec *timeout
current->waiting_lock = lock;
unlock(&current->waiting_cond_lock);
}

int rc = 0;
char saveme[16];
strncpy(saveme, lock->lname, 16); // Save for later
#if LOCK_DEBUG
struct lock_debug lock_tmp = lock->debug;
lock->debug = (struct lock_debug) { .initialized = lock->debug.initialized };
#endif
if (!timeout) { // We timeout anyway after fifteen seconds. It appears the process wakes up briefly before returning here if there is nothing else pending. This is KLUGE. -mke
struct timespec trigger_time;
trigger_time.tv_sec = 15;
trigger_time.tv_nsec = 0;
lock->wait4 = true;

if(current->uid == 501) { // This is here for testing of the process lockup issue. -mke
rc = pthread_cond_timedwait_relative_np(&cond->cond, &lock->m, &trigger_time);
// if((rc == ETIMEDOUT) && current->parent != NULL) {
if(rc == ETIMEDOUT) {
if(current->children.next != NULL) {
notify(cond); // This is a terrible hack that seems to avoid processes getting stuck.
// return 0;
}
}

rc = 0;

} else {
pthread_cond_wait(&cond->cond, &lock->m);
}

if (!timeout) {
// Standard wait on the condition variable without a timeout
rc = pthread_cond_wait(&cond->cond, &lock->m);
} else {
// Timed wait on the condition variable
#if __linux__
struct timespec abs_timeout;
clock_gettime(CLOCK_MONOTONIC, &abs_timeout);
abs_timeout.tv_sec += timeout->tv_sec;
abs_timeout.tv_nsec += timeout->tv_nsec;
if (abs_timeout.tv_nsec > 1000000000) {
if (abs_timeout.tv_nsec >= 1000000000) {
abs_timeout.tv_sec++;
abs_timeout.tv_nsec -= 1000000000;
}
rc = pthread_cond_timedwait(&cond->cond, &lock->m, &abs_timeout);
#elif __APPLE__
rc = pthread_cond_timedwait_relative_np(&cond->cond, &lock->m, timeout);
#else
#error Unimplemented pthread_cond_wait relative timeout.
#error "Platform not supported for pthread_cond_timedwait."
#endif
}
#if LOCK_DEBUG
lock->debug = lock_tmp;
#endif

if(current) {
lock(&current->waiting_cond_lock, 0);
Expand All @@ -115,9 +91,14 @@ int wait_for_ignore_signals(cond_t *cond, lock_t *lock, struct timespec *timeout
unlock(&current->waiting_cond_lock);
}
lock->wait4 = false;
if(rc == ETIMEDOUT)

// Convert the return code from pthreads to the application-specific format
if (rc == ETIMEDOUT)
return _ETIMEDOUT;
return 0;
else if (rc == 0)
return 0;
else
return _EINTR; // or an appropriate error code for other errors
}

void notify(cond_t *cond) {
Expand Down

0 comments on commit b86ad3f

Please sign in to comment.