Cortex-M3 SysTick double interrupt - nested

I'm creating a rtos system, with system tick (1ms) for real-time and trigger pendsv-which used for switch task. Priority of systick and pendsv same as 0 (group = 16; <SCB.AIRCR.PRIGROUP = 0b011>). PendSv also trigger by <SCB.ICSR.PENDSVSET = 1> when current task is sleep.
Sometime, PendSV and SysTick occurs at the same time, and SysTick is executed first, then PendSv. But after PendSV executed, SysTick occurs again.
I was tried by change priority, and clear <SCB.ICSR.PENDSTCLR = 1> in system tick handle, nothing changed.
Do you know why, and how to fix that?
logic_analyzer
asm code:
//#define USING_PUSH_POP
EXTERN GPIOA_BITBAND
EXTERN RTOS_GetCurrentCPU //CPU_TypeDef* RTOS_GetCurrentCPU();
EXTERN RTOS_GetNextCPU //CPU_TypeDef* RTOS_GetNextCPU();
PUBLIC PendSV_Handler
PUBLIC RTOS_ASM_Begin //void RTOS_ASM_ASM_Begin(CPU_TypeDef* CPU);
SECTION rtos_function:CODE
PendSV_Handler:
//PUSH in SP when interrupt
//Here - R0 - R1 - R2 - R3 - R12 - BACK_LR - BACK_PC - EAPSR
PUSH {LR}
LDR.W R0, =GPIOA_BITBAND //(1)
MOV R1, #1
STR R1, [R0, #0x180]
BL RTOS_GetCurrentCPU
CMP R0, #0
BEQ BREAK //if (NULL): back to current task
BL RTOS_ASM_SaveCurrentCPU
BL RTOS_GetNextCPU
CMP R0, #0
BEQ BREAK //if (NULL): back to current task
B RTOS_ASM_SwitchNextCPU
BREAK:
POP {PC}
//===================================
RTOS_ASM_Begin: //R0: CPU_TypeDef* MainCPU
PUSH {R1, LR}
STR LR , [R0, #28]
STR R1 , [R0, #24]
ADDS R1 , R0, #24
MOV SP , R1
BL RTOS_ASM_SaveCurrentCPU
POP {R1, PC}
//===================================
RTOS_ASM_SaveCurrentCPU: //R0: CPU_TypeDef* CurrentCPU
#ifdef USING_PUSH_POP
MOVS R1 , SP
STR SP , [R0, #(4 * 16)]
ADDS R0 , R0, #(4 * 16)
MOVS SP , R0
PUSH {R4-R11}
MOVS SP , R1
#else
STR R4 , [R0, #(4 * 8 )]
STR R5 , [R0, #(4 * 9 )]
STR R6 , [R0, #(4 * 10)]
STR R7 , [R0, #(4 * 11)]
STR R8 , [R0, #(4 * 12)]
STR R9 , [R0, #(4 * 13)]
STR R10, [R0, #(4 * 14)]
STR R11, [R0, #(4 * 15)]
STR SP , [R0, #(4 * 16)]
#endif
BX LR
//===================================
RTOS_ASM_SwitchNextCPU: //R0: CPU_TypeDef* NextCPU
#ifdef USING_PUSH_POP
ADDS R1 , R0, #(4 * 8)
MOVS SP , R1
POP {R4-R11}
LDR SP , [R0, #(4 * 16)]
#else
LDR R4 , [R0, #(4 * 8 )]
LDR R5 , [R0, #(4 * 9 )]
LDR R6 , [R0, #(4 * 10)]
LDR R7 , [R0, #(4 * 11)]
LDR R8 , [R0, #(4 * 12)]
LDR R9 , [R0, #(4 * 13)]
LDR R10, [R0, #(4 * 14)]
LDR R11, [R0, #(4 * 15)]
LDR SP , [R0, #(4 * 16)]
#endif
LDR.W R0, =GPIOA_BITBAND //(2)
MOV R1, #0
STR R1, [R0, #0x180]
POP {PC}
//===================================
END
system tick handle:
void SysTick_Handler()
{
GPIOB_BITBAND.ODR._10 ^= 1; //(3)
System.MsTick++;
if (TaskManager.Running)
RTOS_SWITCH_TRIGGER();
//SCB.ICSR.REG = BIT25;
SCB.ICSR.BITS.PENDSTCLR = 1;
}

My solution now is using SVC instead of PendSV

Related

Array element reversal Implement a RISC-V assembly code snippet that reverses the elements of a 10-element integer array

`I am writing a RISC-V code that will reverse the input number. The input number is 10, the output will be the reverse of this 10 numbers.
like this
A_OUT[9] = A_IN[0]
A_OUT[8] = A_IN[1]
A_OUT[7] = A_IN[2]
but my code's reslut is like this
A_OUT[9] =
A_OUT[8] = A_IN[0]
A_OUT[7] = A_IN[1]
how can I fix my code`
.data
A_IN: .space 40
A_OUT: .space 40
PROMPT: .asciz "Enter an integer: "
.text
main:
\# Load addresses of A_IN and A_OUT into two general purpose registers
la x1, A_IN
la x2, A_OUT
\# Initialize loop index and loop bound for reading 10 integers from console
li x3, 0 # loop index
li x4, 10 # loop bound
LOOP1:
\# Print the prompt
la a0, PROMPT
li a7, 4 # ecall number for printing string
ecall
li a7, 5 # ecall number for reading integer
ecall
addi x3, x3, 1 # increment loop index
sw a0, 0(x1)
addi x1, x1, 4 # move to next location in A_IN
bne x3, x4, LOOP1
li x3, 9 # loop index
li x4, 0 # loop bound
LOOP2:
lw a0, 0(x1)
addi x1, x1, -4 # move to previous location in A_IN
sw a0, 0(x2)
addi x2, x2, 4 # move to next location in A_OUT
addi x3, x3, -1
bge x3, x4, LOOP2
li a7, 10 # ecall number for exit
ecall
As you can see, there is a 0 between two 10, how can I fix it
there is something wrong in the second loop, but i couldn't fix it please keep my style coding, just find the problems

Linux Kernel 5.10 verifier rejects eBPF XDP program that is fine for kernel 5.13

I am writing some eBPF programs in Rust using redBPF and I've encountered some issue with the verifier that only appears on some kernels.
This is a minimal reproducer XDP probe that shows the issue:
#[xdp]
unsafe fn xdp_test(ctx: XdpContext) -> XdpResult {
let data = ctx.data()?;
let start = ctx.data_start();
let off = data.offset();
let end = ctx.data_end();
/* Ensuring an upper bound for off doesn't make any difference
if off > 50 {
return XdpResult::Err(OutOfBounds);
}
*/
let mut address = start + off;
for i in 0..500 {
address = start + off + i;
if address <= start || address >= end {
break;
}
// This line (packet access) fails on kernel 5.10, but works fine on 5.13
let byte = *(address as *const u8);
// Just so the packet read above doesn't get optimized away
printk!("%u", byte as u32);
}
Ok(XdpAction::Pass)
}
Compiling this into eBPF bytecode and loading it into an Ubuntu 5.13 kernel (5.13.0-48-generic #54~20.04.1-Ubuntu SMP Thu Jun 2 23:37:17 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux) works without issues. The verifier accepts the program.
However, trying to load the exact same bytecode into an Android emulator kernel 5.10.66-android12-9-00041-gfa9c9074531e-ab7914766 #1 SMP PREEMPT Fri Nov 12 11:36:25 UTC 2021 x86_64 the verifier rejects the program. This is the full error log from the verifier:
ret=-1 os error=Permission denied (os error 13): 0: (61) r6 = *(u32 *)(r1 +4)
1: (61) r7 = *(u32 *)(r1 +0)
2: (bf) r1 = r7
3: (07) r1 += 14
4: (2d) if r1 > r6 goto pc+43
R1_w=pkt(id=0,off=14,r=14,imm=0) R6_w=pkt_end(id=0,off=0,imm=0) R7_w=pkt(id=0,off=0,r=14,imm=0) R10=fp0
5: (71) r2 = *(u8 *)(r7 +13)
6: (67) r2 <<= 8
7: (71) r3 = *(u8 *)(r7 +12)
8: (4f) r2 |= r3
9: (55) if r2 != 0x8 goto pc+38
R1_w=pkt(id=0,off=14,r=14,imm=0) R2_w=inv8 R3_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff)) R6_w=pkt_end(id=0,off=0,imm=0) R7_w=pkt(id=0,off=0,r=14,imm=0) R10=fp0
10: (bf) r2 = r7
11: (07) r2 += 34
12: (2d) if r2 > r6 goto pc+35
R1=pkt(id=0,off=14,r=34,imm=0) R2=pkt(id=0,off=34,r=34,imm=0) R3=inv(id=0,umax_value=255,var_off=(0x0; 0xff)) R6=pkt_end(id=0,off=0,imm=0) R7=pkt(id=0,off=0,r=34,imm=0) R10=fp0
13: (71) r3 = *(u8 *)(r1 +0)
14: (67) r3 <<= 2
15: (57) r3 &= 60
16: (71) r2 = *(u8 *)(r1 +9)
17: (0f) r1 += r3
last_idx 17 first_idx 12
regs=8 stack=0 before 16: (71) r2 = *(u8 *)(r1 +9)
regs=8 stack=0 before 15: (57) r3 &= 60
regs=8 stack=0 before 14: (67) r3 <<= 2
regs=8 stack=0 before 13: (71) r3 = *(u8 *)(r1 +0)
18: (15) if r2 == 0x11 goto pc+31
R1_w=pkt(id=1,off=14,r=0,umax_value=60,var_off=(0x0; 0x3c)) R2_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff)) R3_w=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R6=pkt_end(id=0,off=0,imm=0) R7=pkt(id=0,off=0,r=34,imm=0) R10=fp0
19: (55) if r2 != 0x6 goto pc+28
R1_w=pkt(id=1,off=14,r=0,umax_value=60,var_off=(0x0; 0x3c)) R2_w=inv6 R3_w=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R6=pkt_end(id=0,off=0,imm=0) R7=pkt(id=0,off=0,r=34,imm=0) R10=fp0
20: (2d) if r7 > r1 goto pc+27
R1=pkt(id=1,off=14,r=0,umax_value=60,var_off=(0x0; 0x3c)) R2=inv6 R3=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R6=pkt_end(id=0,off=0,imm=0) R7=pkt(id=0,off=0,r=34,imm=0) R10=fp0
21: (bf) r2 = r1
22: (07) r2 += 20
23: (2d) if r2 > r6 goto pc+24
R1=pkt(id=1,off=14,r=34,umax_value=60,var_off=(0x0; 0x3c)) R2_w=pkt(id=1,off=34,r=34,umax_value=60,var_off=(0x0; 0x3c)) R3=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R6=pkt_end(id=0,off=0,imm=0) R7=pkt(id=0,off=0,r=34,imm=0) R10=fp0
24: (71) r2 = *(u8 *)(r1 +12)
25: (77) r2 >>= 2
26: (57) r2 &= 60
27: (0f) r1 += r2
last_idx 27 first_idx 20
regs=4 stack=0 before 26: (57) r2 &= 60
regs=4 stack=0 before 25: (77) r2 >>= 2
regs=4 stack=0 before 24: (71) r2 = *(u8 *)(r1 +12)
28: (2d) if r7 > r1 goto pc+19
R1=pkt(id=2,off=14,r=0,umax_value=120,var_off=(0x0; 0x7c),s32_max_value=124,u32_max_value=124) R2=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R3=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R6=pkt_end(id=0,off=0,imm=0) R7=pkt(id=0,off=0,r=34,imm=0) R10=fp0
29: (bf) r8 = r1
30: (3d) if r1 >= r6 goto pc+17
R1=pkt(id=2,off=14,r=13,umax_value=120,var_off=(0x0; 0x7c),s32_max_value=124,u32_max_value=124) R2=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R3=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R6=pkt_end(id=0,off=0,imm=0) R7=pkt(id=0,off=0,r=34,imm=0) R8_w=pkt(id=2,off=14,r=13,umax_value=120,var_off=(0x0; 0x7c),s32_max_value=124,u32_max_value=124) R10=fp0
31: (bf) r1 = r8
32: (1f) r1 -= r7
33: (25) if r1 > 0x32 goto pc+14
R1_w=inv(id=0,umax_value=50,var_off=(0x0; 0xffffffff)) R2=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R3=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R6=pkt_end(id=0,off=0,imm=0) R7=pkt(id=0,off=0,r=34,imm=0) R8_w=pkt(id=2,off=14,r=13,umax_value=120,var_off=(0x0; 0x7c),s32_max_value=124,u32_max_value=124) R10=fp0
34: (b7) r9 = 0
35: (bf) r1 = r8
36: (0f) r1 += r9
last_idx 36 first_idx 28
regs=200 stack=0 before 35: (bf) r1 = r8
regs=200 stack=0 before 34: (b7) r9 = 0
37: (3d) if r7 >= r1 goto pc+10
R1=pkt(id=2,off=14,r=13,umax_value=120,var_off=(0x0; 0x7c),s32_max_value=124,u32_max_value=124) R2=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R3=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R6=pkt_end(id=0,off=0,imm=0) R7=pkt(id=0,off=0,r=34,imm=0) R8=pkt(id=2,off=14,r=13,umax_value=120,var_off=(0x0; 0x7c),s32_max_value=124,u32_max_value=124) R9=invP0 R10=fp0
38: (3d) if r1 >= r6 goto pc+9
R1=pkt(id=2,off=14,r=13,umax_value=120,var_off=(0x0; 0x7c),s32_max_value=124,u32_max_value=124) R2=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R3=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R6=pkt_end(id=0,off=0,imm=0) R7=pkt(id=0,off=0,r=34,imm=0) R8=pkt(id=2,off=14,r=13,umax_value=120,var_off=(0x0; 0x7c),s32_max_value=124,u32_max_value=124) R9=invP0 R10=fp0
39: (71) r3 = *(u8 *)(r1 +0)
invalid access to packet, off=14 size=1, R1(id=2,off=14,r=13)
R1 offset is outside of the packet
processed 40 insns (limit 1000000) max_states_per_insn 0 total_states 4 peak_states 4 mark_read 2
As I understand the issue, the verifier of the 5.10 kernel rejects the dereferencing of the packet pointer, claiming that we don't have validated that it is always within bounds (reading at offset 14 while r is 13). We do in fact check this just above.
Interestingly, if I oversize the bounds check above to something like this, both the 5.10 and 5.13 kernel verifiers accept the program:
[snip]
for i in 0..500 {
address = start + off + i;
// Checking 2 bytes ahead makes 5.10 verifier happy
if address <= start || (address + 2) >= end {
break;
}
// Works on both 5.10 and 5.13
let byte = *(address as *const u8);
// Just so the packet read above doesn't get optimized away
printk!("%u", byte as u32);
}
Ok(XdpAction::Pass)
}
But the above is not what I want, because this causes the bounded loop to abort too early - I want the loop to run fully, if the packet is large enough. I have tried the usual tricks I do when I run into verifier issues, but so far to no avail. I don't quite understand why the 5.10 verifier is unhappy with the first example. Usually this is related to some unbounded registers, but as far as I can see all bounds should be satisfied.
I have tried looking at a diff of the kernel verifier between the two versions, but couldn't see any obvious change that causes this.
TL;DR. You are missing bug fix 2fa7d94afc1a for the BPF verifier. It was backported to the v5.13 kernel you are using as commit e7a61f15beea, but not to the v5.10 kernel.
You might want to try a newer Android kernel if possible, or to ask them to carry the bugfix if they don't on v5.10.
Verifier Error Explanation
I removed parts of the output that were irrelevant here.
R1=pkt(id=2,off=14,r=0,umax_value=120,var_off=(0x0; 0x7c),s32_max_value=124,u32_max_value=124) R2=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R3=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R6=pkt_end(id=0,off=0,imm=0) R7=pkt(id=0,off=0,r=34,imm=0) R10=fp0
29: (bf) r8 = r1
30: (3d) if r1 >= r6 goto pc+17
R1=pkt(id=2,off=14,r=13,umax_value=120,var_off=(0x0; 0x7c),s32_max_value=124,u32_max_value=124) R2=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R3=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R6=pkt_end(id=0,off=0,imm=0) R7=pkt(id=0,off=0,r=34,imm=0) R8_w=pkt(id=2,off=14,r=13,umax_value=120,var_off=(0x0; 0x7c),s32_max_value=124,u32_max_value=124) R10=fp0
[...]
34: (b7) r9 = 0
35: (bf) r1 = r8
36: (0f) r1 += r9
37: (3d) if r7 >= r1 goto pc+10
R1=pkt(id=2,off=14,r=13,umax_value=120,var_off=(0x0; 0x7c),s32_max_value=124,u32_max_value=124) R2=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R3=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R6=pkt_end(id=0,off=0,imm=0) R7=pkt(id=0,off=0,r=34,imm=0) R8=pkt(id=2,off=14,r=13,umax_value=120,var_off=(0x0; 0x7c),s32_max_value=124,u32_max_value=124) R9=invP0 R10=fp0
38: (3d) if r1 >= r6 goto pc+9
R1=pkt(id=2,off=14,r=13,umax_value=120,var_off=(0x0; 0x7c),s32_max_value=124,u32_max_value=124) R2=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R3=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R6=pkt_end(id=0,off=0,imm=0) R7=pkt(id=0,off=0,r=34,imm=0) R8=pkt(id=2,off=14,r=13,umax_value=120,var_off=(0x0; 0x7c),s32_max_value=124,u32_max_value=124) R9=invP0 R10=fp0
39: (71) r3 = *(u8 *)(r1 +0)
invalid access to packet, off=14 size=1, R1(id=2,off=14,r=13)
R1 offset is outside of the packet
The verifier tells us that we are trying to access the packet at offset 14 (off=14) with an access size of 1 byte when the packet is only known to be at least 13 bytes long (r=13). The known packet length here is incorrect somehow because you checked that address >= end.
Going up, we can check where that packet range (r=13) is coming from. It is assigned from R8 at instruction 35, itself assigned from R1 at instruction 29.
At instruction 30, we find the address >= end check in its bytecode form. We see that both R1 and R8's ranges are updated from r=0 to r=13 after this check. That is however incorrect and should be updated to off+1, hence r=15.
Checking the Verifier Sources
In the verifier, this update of the range is implemented in find_good_pkt_pointers. The update logic looks fine and shouldn't cause this issue.
But if we git blame those lines, we can see they were changed in commit 2fa7d94afc1a. The commit describes the off-by-two error you are hitting:
This commit fixes the off-by-two error by adjusting new_range in the
right direction and fixes the tests by changing the range into the
one that should actually fail.
This commit was released upstream in v5.16. Checking the Ubuntu sources for Ubuntu-hwe-5.13-5.13.0-48.54_20.04.1, we find this same commit backported as e7a61f15beea, which explains why it works on your v5.13 kernel.

How to use scipy.integrate.odeint(func, y0, t, args=(),...) when there are some constraints among the parameters of the function "func"?

Here is my attempt to solve a system of ordinary differential equations given some initial conditions and constraints. While I have figured out how to solve the ODE using odeint from Scipy package without the constraints, I do not know how to incorporate the existence of two constraints on the parameters of the function (which are commented out in the code).
I would truly appreciate your help.
Note: any undefined variable in the code is actually some fixed scalar.
import numpy as np
from scipy.integrate import odeint
#initial conditions
y0, u0 = ([2.1E19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [2.1E19, 0, 0, 0])
def lhs(y):
"""This function extracts all 13 components of the solution y"""
return y[0], y[1], y[2], y[3], y[4], y[5], y[6], y[7], y[8], y[9], y[10], y[11], y[12]
def eqns(time_val, y, f_func, g_func, h_func, p_func, diff_eq_solutions_num):
"This is the system of equations that needs to be solved numerically"
var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13 = lhs(y)
#var1
r0 = -(K2 * var11 * var1) - ((K4+K5) * var11 * var1) + (0.5 * (K6+K7) * var2**2) + (
2*K12*var11*var8) - (K11 * var1 * (var5+var6+var7)) + (Qa*var2*var9) + (Qb*var3*var1) + (
Qc*var4*var1) + (A4*var7) + (A5*var6) - (
(K14+K15) * var11 * var1) - (f_func(time_val) * var1) - (
g_func(time_val) * var1) - (G1+G2+G3+G4) * h_func(time_val)
#var2
r1 = (A2*var3) - ((K6+K7) * var2**2) - (K11 * var2 * (var5+var6+var7)) + (
K3 * f1 * var11 *
(var5+var6+var7)) + (K14*var11*var1) - (Qa*var9*var2) + G2 * f1 * h_func(time_val)
#var3
r2 = (A1*var4) - (A2*var3) + (0.5 * K6 * var2**2) - (K11 * var3 * (var5+var6+var7)) - (
Qb*var3*var1) + (K10 * var1 * var9**2) + (K15*var11*var1) + (
K3 * f2 * var11 * (var5+var6+var7)) + G2 * f2 * h_func(time_val)
#var4
r3 = (K3 * f3 * var11 * (var5+var6+var7)) - (A1*var4) - (Qc*var4*var1) + (K7*var2*var2) - (
K11 * var4 * (var5+var6+var7)) + (f_func(time_val) * var1) + G2 * f3 * h_func(time_val)
#var5
r4 = (K2*fi1*var11*var1) - (K3*var11*var5) - (K8*var11*var5) - (K11*var1*var5) + (A5*var6) + (
A4*var7) + (Qi1*var7*var1) + (Qi2*var7*NO2) + (fi1 * g_func(time_val) *
var1) + G1 * fi1 * h_func(time_val)
#var6
r5 = (K2*fi2*var11*var1) - (K3*var11*var6) - (A5*var6) - (K8*var11*var6) - (K11*var1*var5) + (
fi2 * g_func(time_val) * var1) + G1 * fi3 * h_func(time_val)
#var7
r6 = (K2*fi3*var11*var1) - (K3*var11*var7) - (A4*var7) - (Qi1*var7*var1) - (K8*var11*var7) - (
Qi2*var7*NO2) + (fi3 * g_func(time_val) * var1) + G1 * fi2 * h_func(time_val)
#var8
r7 = (K11 * (var5+var6+var7) * (var1+var2+var3+var4)) - (K12*var11*var8)
#var9
r8 = (K4*var11*var1) + (2*K5*var11*var1) + (2 * K8 * var11 * (var5+var6+var7)) - (
K9*var11*var9) - (K10 * var1 * var9**2) + (K13*var11*var10) + G4 * h_func(time_val)
#var10
r9 = (K4*var11*var1) + (K9*var11*var9) - (K13*var11*var10) + G3 * h_func(time_val)
r10 = -(K8 * var11 * (var5+var6+var7)) + (K9*var11*var9) - (K13*var11*var10) - (
K12*var11*var8) - (K3 * var11 *
(var5+var6+var7)) + p_func(time_val) + G5 * h_func(time_val) + (
K4*var11*var1) + (K2*var11*var1)
r11 = (A1*var4) - (4 * np.pi * var12 / 3E-11)
r12 = (A4*var7) - (4 * np.pi * var13 / 3E-11)
#These are the constraints I would like to incorporate into system of differential equations
# 2.1E19 = var1 + var2 + var3 + var4 + var5 + var6 + var7 + var8 + var9 + var10
# 0 = var5 + var6 + var7 + var8 + var10 - var11
return [r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12]
def integrator(soln, f_func, g_func, p_func, h_func, i, j, diff_eq_solutions_num):
args = (f_func[i][j], g_func[i][j], p_func[i][j], h_func[i][j], diff_eq_solutions_num)
t = np.linspace(0, 2E-6, 100000)
soln[i][j] = odeint(eqns, y0, t, args=args, tfirst=True, printmessg=True, ixpr=True)

x87 - Issue in raymarcher

Below is my raymarcher, mostly adapted from https://www.shadertoy.com/view/llt3R4#
The expected behavior is a projection of a sphere on the screen, but instead it projects
empty space (signified by a yellow pixel, instead of a purple one).
This is my first program written using the x87 coprocessor, so I am unsure if there is anything I'm missing.
A few programmers I know have looked it over without finding a problem, so I am unsure of what to do.
macro bareintro {
org 0x7c00
jmp 0x0:boot
boot:
xor ax, ax
mov ds, ax
mov ss, ax
}
macro zerob b {
times b db 0
}
bareintro
mov ax, 0x13
int 0x10
mov ax, 0xA000
mov es, ax
xor di, di
y_loop:
mov word [ix], 0
mov bx, [iy]
inc bx
cmp bx, 200
je y_end
mov [iy], bx
x_loop:
; first calculate the raymarching direction:
; vec3 rayDirection(float fieldOfView, vec2 size, vec2 fragCoord) {
; vec2 xy = fragCoord - size / 2.0;
; float z = size.y / tan(radians(fieldOfView) / 2.0);
; return normalize(vec3(xy, -z));
; }
fld qword [h]
fld qword [z_diri]
fmulp
fld qword [y_diri]
fild word [iy]
faddp
fld qword [x_diri]
fild word [ix]
faddp
; finally, normalize vector
; do a couple dupes
fld st2
fld st2
fld st2
call len
fdiv st1, st0
fdiv st2, st0
fdivp st3, st0
; store in respective memory locations
fstp qword [dir_x]
fstp qword [dir_y]
fstp qword [dir_z]
call sdts
setc al
add al, 13
stosb
inc word [ix]
cmp word [ix], 319
ja y_loop
jmp x_loop
y_end:
cli
hlt
; int intersect(float rayx, float rayy, float rayz) {
; float depth = MIN_DIST;
; for(int i = 0; i < STEPS; i++) {
; float vx = rayx * depth;
; float vy = rayy * depth;
; float vz = rayz * depth + 5.0;
; float dist = sdf(vx, vy, vz);
; if(dist < EPS) {
; return 1;
; }
; depth += dist;
; if(depth >= MAX_DIST) {
; return 0;
; }
; }
; return 0;
;}
sdts:
fldz
fstp qword [.depth]
mov cx, 255
.loop:
; float dist = sceneSDF(eye + depth * marchingDirection);
; load in direction vector
fld qword [dir_z]
fld qword [dir_y]
fld qword [dir_x]
fld qword [.depth]
fmul st1, st0
fmul st2, st0
fmulp st3, st0
fld qword [eyez]
fld qword [eyey]
fld qword [eyex]
faddp st3, st0
faddp st3, st0
faddp st3, st0
.sdf:
; single sphere for now (len(p) - radius)
call len
; - radius
fld qword [radius]
fsubp st1, st0
.endsdf:
; EPS <=> Dist
fld qword [eps]
fcomip st0, st1
jb .nohit
; cowabunga!
clc
ret
.nohit:
fld qword [.depth]
; MAX <=> Total
faddp
fld qword [.max_depth]
fcomip st0, st1
fstp qword[.depth]
ja .alsofine
stc
ret
.alsofine:
loop .loop
.endloop:
stc
ret
.max_depth:
dq 100.0
.depth:
dq 0.0
; st0 <- sqrt(s0^2 + s1^2 + s2^2)
len:
fmul st0, st0
fxch st1
fmul st0, st0
faddp st1, st0
fxch st1
fmul st0, st0
faddp st1, st0
fsqrt
ret
x_diri:
dq -160.000
y_diri:
dq -100.000
z_diri:
dq 482.8427
dir_x:
dq -160.000
dir_y:
dq -100.000
dir_z:
dq -2.4142135623911343
w:
dq 320.0
h:
dq 200.0
radius:
dq 1.0
eps:
dq 0.001
eyex:
dq 0.0
eyey:
dq 0.0
eyez:
dq 5.0
ix:
dw 0
iy:
dw 0
zerob 510 - ($-$$)
dw 0xaa55
(Here is a working version of the code in C)
#include <math.h>
#include <SDL2/SDL.h>
const int STEPS = 256;
const float MIN_DIST = 0.0;
const float MAX_DIST = 100.0;
const float EPS = 0.001;
float sdf(float x, float y, float z) {
float len = sqrt(x*x + y*y + z*z);
return len - 1.0;
}
int intersect(float rayx, float rayy, float rayz) {
float depth = MIN_DIST;
for(int i = 0; i < STEPS; i++) {
float vx = rayx * depth;
float vy = rayy * depth;
float vz = rayz * depth + 5.0;
float dist = sdf(vx, vy, vz);
if(dist < EPS) {
return 1;
}
depth += dist;
if(depth >= MAX_DIST) {
return 0;
}
}
return 0;
}
int main() {
SDL_Init(SDL_INIT_EVERYTHING);
uint32_t buff[320*200];
SDL_Window* win;
SDL_Renderer* ren;
SDL_CreateWindowAndRenderer(320, 200, 0, &win, &ren);
SDL_Texture* tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC,
320, 200);
for(size_t y = 0; y < 200; y++) {
for(size_t x = 0; x < 320; x++) {
float r_z = -200.0 / 0.41421356237;
float r_y = ((float)y) - 100.0;
float r_x = ((float)x) - 160.0;
float len = sqrt(r_x*r_x + r_y*r_y + r_z*r_z);
r_x /= len;
r_y /= len;
r_z /= len;
buff[y*320 + x] = (-1) * intersect(r_x, r_y, r_z);
}
}
SDL_UpdateTexture(tex, NULL, buff, 320*4);
SDL_RenderCopy(ren, tex, NULL, NULL);
SDL_RenderPresent(ren);
SDL_Event e;
while(1) {
SDL_WaitEvent(&e);
if(e.type == SDL_QUIT) {
SDL_Quit();
return 0;
}
}
return 0;
}

Leaks shows a leak when allocating a UILabel, [NSNotificationCenter addObserver], appears to be "UIAccessibilityButtonShapesChangedNotification"

We first became curious when our largest leaks were from NSNotification addObserver frames,
If you look at the Stack Trace, it looks like it's happening when we initialize a UILabel.
Here is our relevant code:
final class TileView: UIView {
fileprivate let digitLabel = UILabel()
fileprivate let mainLineView = UIView()
fileprivate let secondaryLineView = UIView()
...
required init(builder: FlapViewBuilder, position: Position) {
self.cornerRadii = CGSize(width: builder.cornerRadius, height: builder.cornerRadius)
self.position = position
super.init(frame: CGRect.zero)
setupViewsWithBuilder(builder)
}
I set a symbolic breakpoint at for addObserver, and caught the frame that was leaking. I checked out the registers:
(lldb) register read
General Purpose Registers:
x0 = 0x0000000283c937e0
x1 = 0x00000001df7310a8 #"UIAccessibilityButtonShapesChangedNotification"
x2 = 0x00000001d8b763e8 #"kCFNotificationAnyObject"
x3 = 0x0000000000000400
x4 = 0x0000000108e1dcb0
x5 = 0x0000000000000000
x6 = 0x000000016d72e4a0
x7 = 0x0000000000000000
x8 = 0x00000001a9493e74 Foundation`__57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke_2
x9 = 0x00000001d8d0e2b0 Foundation`__block_descriptor_48_e8_v16#?0#8l
x10 = 0x000000010b814800
x11 = 0x0000013f000001ff
x12 = 0x000000010b8154a0
x13 = 0x000001a1e23c6b97 (0x00000001e23c6b97) (void *)0x000001e23c738800
x14 = 0x000000000000000f
x15 = 0x00000001e238c95a __CFCharToUniCharTable
x16 = 0x00000001e23c6b90 (void *)0x000001a1e23c6bb9
x17 = 0x00000001a7c0b250 libobjc.A.dylib`-[NSObject class]
x18 = 0x0000000000000000
x19 = 0x0000000108e1dcb0
x20 = 0x00000001d5615e89 "_accessibilityButtonShapesChangedNotification:"
x21 = 0x00000001df7310a8 #"UIAccessibilityButtonShapesChangedNotification"
x22 = 0x0000000000000000
x23 = 0x0000000283396370
x24 = 0xfffffffef71e234f
x25 = 0x0000000102e91000 "setShouldRasterize:"
x26 = 0x0000000ffffffff8
x27 = 0x00000001027c2054 Sideline`protocol witness for Sideline.SplitflapDelegate.splitflap(_: Sideline.Splitflap, builderForFlapAtIndex: Swift.Int) -> Sideline.FlapViewBuilder in conformance Sideline.SplitflapView : Sideline.SplitflapDelegate in Sideline at <compiler-generated>
x28 = 0x000000010cc878d0
fp = 0x000000016d72e500
lr = 0x00000001a938d1a8 Foundation`-[NSNotificationCenter addObserver:selector:name:object:] + 256
sp = 0x000000016d72e4a0
pc = 0x00000001a938d224 Foundation`-[NSNotificationCenter addObserver:selector:name:object:] + 380
cpsr = 0x60000000
Saw this: "UIAccessibilityButtonShapesChangedNotification"
Is there anything we can do about this?
Maybe just a bug with UILabel/UIKit?
Or I'm misinterpreting the results of the Leaks report?

Resources