Mutex Problem (Or Anything Else) in SMP Scheduling

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
User avatar
Js2xxx
Member
Member
Posts: 48
Joined: Sat Dec 31, 2016 1:43 am
Libera.chat IRC: wrgq
Location: China

Re: Mutex Problem (Or Anything Else) in SMP Scheduling

Post by Js2xxx »

Brendan wrote:at the end of this post.[/i]
Before creating the topic, I've already got a structure of thread and process:

Code: Select all

typedef     struct s_regs
{
      qword r15, r14, r13, r12, r11, r10, r9, r8;
      qword rdi, rsi, rbp, kernel_rsp, rdx, rbx, rcx, rax;
      qword Rsvd;
      qword rip, cs, rflags, rsp, ss;
} RegImage;

typedef     enum  e_tstate
{
      Created     = 0,
      Ready       = 1,
      Running     = 2,
      Waiting     = 3,
      Halted      = 4
} ThrdState;

typedef     struct s_thrd
{
      RegImage    Regs;
      short       TId;
      Action      Entry;
      short       ParentId;
      short       ProcId;
      ThrdState   State;
      int         Priority;
      int         Ticks;
} Thread;

typedef     struct s_proc
{
      short       PId;
      int         UserId;
      char        Name[16];
      int         ThreadsId[MAX_THRD_PER_PROC];
} Process;
A Thread deriver:

Code: Select all

public int DeriveT(int tid, int pcsr, Action entry, int priority);//'public' is a macro defined nothing and 'private' is defined as 'static'
And three test thread bodies:

Code: Select all

public int Init()
{
      while(1)
      {
            DispStr("I.");
            LittleDelay();
      }
}

public int Child1()
{
      while(1)
      {
            DispStr("A.");
            LittleDelay();
      }
}

public int Child2()
{
      while(1)
      {
            DispStr("B.");
            LittleDelay();
      }
}
The code to first enter threads:

Code: Select all

Restart:
	lldt	[rel LdtSel]
	mov	rax, [rel CurrentT]

	mov	rsp, [rax]
	lea	rax, [rsp + 22 * 8]
	mov	rbx, 0xFFFFFF8000601800
	mov	qword [rbx + 4], rax
	pop	r15
	pop	r14
	pop	r13
	pop	r12
	pop	r11
	pop	r10
	pop	r9
	pop	r8
	pop	rdi
	pop	rsi
	pop	rbp
	add	rsp, 8
	pop	rbx
	pop	rdx
	pop	rcx
	pop	rax

	add	rsp, 8

	mov	rdi, RestartLock
	call	LeaveSpinLock
	
	iretq
The thing I haven't implemented is only blocking and IPC so certainly I've got to redesign my scheduler.
So hasn't the code above got any mistakes?
Doing steadfastly, or doing nil.
User avatar
Js2xxx
Member
Member
Posts: 48
Joined: Sat Dec 31, 2016 1:43 am
Libera.chat IRC: wrgq
Location: China

Re: Mutex Problem (Or Anything Else) in SMP Scheduling

Post by Js2xxx »

Wait.
I found where I failed:

Code: Select all

Restart:
...
   mov   rax, [rel CurrentT]

   mov   rsp, [rax]
   lea   rax, [rsp + 22 * 8]
   mov   rbx, 0xFFFFFF8000601800; The TSS structure address
   mov   qword [rbx + 4], rax
...
I have set the same TSS for all the processors!!!! What a simple mistake!!! It shocked me :shock: !!!! I was so careless!!!!
So I quickly changed:

Code: Select all

Restart:
...
	movzx	rax, di; di contains the processor id
	mov	rbx, 0x100; TSS offset of each processor
	mul	rbx
	mov	rbx, 0xFFFFFF8000601800
	add	rbx, rax
	mov	rax, [rel CurrentT]
	mov	rsp, [rax]
	lea	rax, [rsp + 22 * 8]
	mov	qword [rbx + 4], rax
...
And it eventually works well!!!!

However, when switching happens, 'B'(running in the processor with logical id 1) is replaced by 'A'(running in the processor with logical id 0), and the original 'A' is still in presence, just like 'fork'.
What's the problem?
Doing steadfastly, or doing nil.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Mutex Problem (Or Anything Else) in SMP Scheduling

Post by Brendan »

Hi,
Js2xxx wrote:So hasn't the code above got any mistakes?
For this:

Code: Select all

typedef     struct s_regs
{
      qword r15, r14, r13, r12, r11, r10, r9, r8;
      qword rdi, rsi, rbp, kernel_rsp, rdx, rbx, rcx, rax;
      qword Rsvd;
      qword rip, cs, rflags, rsp, ss;
} RegImage;
I don't know why you think you need most of those fields - for long mode I'd want "rsp" and "cr3" somewhere (e.g. in "struct s_thrd") and (assuming AMD64 ABI) the "struct s_regs" would only contain RBP, RBX, and R12 to R15.

I have no idea what a "thread deriver" does.

For the code to first enter threads; in long mode the LDT should be constant (and should probably be zero) and shouldn't need to be changed (other than a single "lldt" to set it to zero when switching to long mode during boot). It's also suffering from the same "complete lack of any comments" problem as your earlier code and has the (not mentioned previously) same "proliferation of magic numbers" problem (e.g. (e.g. 22*8, 0xFFFFFF8000601800, etc - these should be given meaningful names).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Js2xxx
Member
Member
Posts: 48
Joined: Sat Dec 31, 2016 1:43 am
Libera.chat IRC: wrgq
Location: China

Re: Mutex Problem (Or Anything Else) in SMP Scheduling

Post by Js2xxx »

"thread deriver" is to create thread and kick the new thread into the ready queue. (fork() and exec())

Code: Select all

public int DeriveT(int tid, int pcsr, Action entry, int priority);
"tid" means the parent id; "pcsr" means processor affinity; "entry" means the main function of the thread; and "priority" means itself.

It's a pretty good advice to comment my code so I do this and my code becomes more readable. Thanks!

According to my last post, how is 'B' replaced by 'A'?
EDIT: The same in 2, 3 and 4 processors.
Doing steadfastly, or doing nil.
Post Reply