OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Mar 19, 2024 5:22 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: Assignment operation not assigning?!
PostPosted: Sat Aug 21, 2021 11:18 pm 
Offline
Member
Member

Joined: Sun Aug 23, 2020 4:35 pm
Posts: 148
I've been trying to implement an inter-process communication method in which a program can listen on a port (not related to networking at all, it's sort of like a mailbox identifier) and another program can send data to that port.
Additionally, I've implemented a function that waits for IPC data on either a specified port or any port called waitipc:
Code:
void waitipc(uint32_t port) {
   if (!verify_ipc_port_ownership(port))
      yield();

   dprintf("Port is %u\n", port);

   current_task->state = TASK_STATE_WAITIPC;
   current_task->waitval = port;
   dprintf("Port is %u\n", current_task->waitval);
   yield();
}
The code executes fine until it reaches current_task->waitval = port;
At this point it acts like it assigns the value of port to the current task's waitval, but it actually does NOTHING.
The first dprintf (debug printf, goes to serial) says "Port is 24576" (which is correct as it is supposed to wait for port 0x6000).
The second dprintf says "Port is 0" which is wrong, even though it is set in the line before it!
I've verified this with GDB too.

What could be the cause of this? Is it being optimized out somehow?

(Note: I will try to upload the full code to GitHub soon)

_________________
My OS: TritiumOS
https://github.com/foliagecanine/tritium-os
void warranty(laptop_t laptop) { if (laptop.broken) return laptop; }
I don't get it: Why's the warranty void?


Top
 Profile  
 
 Post subject: Re: Assignment operation not assigning?!
PostPosted: Sun Aug 22, 2021 12:55 am 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 1590
Is it possible that another process or some interrupt handler is writing to whatever memory you use for "current_task"? Is "current_task" in normal RAM? These are just two pitfalls I can imagine from the top of my head.

You could try to enlist the help of the Debug Registers to find the culprit. Just register "waitport" as a write break point for some task and see where the interrupts are coming from.

_________________
Carpe diem!


Top
 Profile  
 
 Post subject: Re: Assignment operation not assigning?!
PostPosted: Sun Aug 22, 2021 5:27 am 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 1584
There are three things that could go wrong here:

- another task is modifying the current_task struct. As @nullplan said, try to put a write break on it with gdb and see if this is the case
- another task changes the current_task pointer, so it is pointing to a different (potentially empty) struct
- you have caching issues. The paging changed, but cache not flushed. Flushing happens occasionally between the two dprint calls.

Your locking is insufficient. You just check if the lock is acquired, but since your entire waitipc isn't atomic, it can lost ownership after the check and before the function ends. Try something like
Code:
{
  if (!can_acquire_ownership(port))
     yield();
...
  release_lock(port);
  yield();
}
You'll need no caching and special assembly instructions (or LOCK prefix) for those functions if you're using SMP, otherwise CLI / STI might suffice. I recommend to declare the lock variable as volatile too so that the compiler won't optimize it and generates code that always reads its value from memory. Best to use one of the atomic test and set built-ins.

Cheers,
bzt


Top
 Profile  
 
 Post subject: Re: Assignment operation not assigning?!
PostPosted: Sun Aug 22, 2021 9:33 am 
Offline
Member
Member

Joined: Sun Aug 23, 2020 4:35 pm
Posts: 148
I figured out what it was and am rather surprised the compiler didn't warn me...
The problem:
waitval was an 8-bit value, I was writing a 16 bit value where the low 8 bits = 0. #-o

I don't know why waitval was 8 bit, since my pid type (which also uses the waitval variable for waitpid) should be 32 bit, but at least I found the error.

Am I missing a compiler warning flag that would have helped me here?

As for locking, this isn't necessary if you don't have multiprocessing (assuming I make sure the interrupts don't interfere), correct?

_________________
My OS: TritiumOS
https://github.com/foliagecanine/tritium-os
void warranty(laptop_t laptop) { if (laptop.broken) return laptop; }
I don't get it: Why's the warranty void?


Top
 Profile  
 
 Post subject: Re: Assignment operation not assigning?!
PostPosted: Sun Aug 22, 2021 10:12 am 
Offline
Member
Member

Joined: Tue Apr 03, 2018 2:44 am
Posts: 399
foliagecanine wrote:
As for locking, this isn't necessary if you don't have multiprocessing (assuming I make sure the interrupts don't interfere), correct?


You could design your critical section round disabling interrupts, but you'd be better off hiding that detail, so you can change the details to support SMP without changing client code. Put your critical section lock/unlock in a subroutine, and rely on compiler optimisation to obviate the subroutine overhead.


Top
 Profile  
 
 Post subject: Re: Assignment operation not assigning?!
PostPosted: Sun Aug 22, 2021 2:58 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5069
foliagecanine wrote:
Am I missing a compiler warning flag that would have helped me here?

-Wconversion


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group