// File: /workspace/github_cpp_makefile_star2_O1/maramire[P]SP_PSO/parallel_main.cpp
// Function: particle_function(void*)
void* particle_function(void* arg){
    
    long p = (long)arg;

    random_device rd;
    mt19937 gen(rd());
    uniform_real_distribution<> dis(0, 1);//uniform distribution between 0 and 1
    
    /* Each thread run */
    /* Particle movement */
    vector<float> new_permutation(n_items);
    iota(begin(new_permutation), end(new_permutation), 1);

    for (int i = 0; i < swarm[p].permutation.size(); i++)
    {
    
        float r1 = dis(gen);
        float r2 = dis(gen);

        float pfactor = swarm[p].pbest[i] - swarm[p].permutation[i];
        float gfactor = gbest.permutation[i] - swarm[p].permutation[i];                

        float current_velocity = omega*swarm[p].permutation[i] + r1*c1*pfactor + r2*c2*gfactor;

        if (current_velocity < velocity_min)
        {
            current_velocity = velocity_min;

        }else if(current_velocity > velocity_max)
        {
            current_velocity = velocity_max;
        }

        swarm[p].velocity[i] = current_velocity;
    
        new_permutation[i] = swarm[p].permutation[i] + swarm[p].velocity[i];
        
    }

    /* Discretize Movement */
    vector<float> assignments = new_permutation;
    sort(assignments.begin(),assignments.end());

    for (int i = 0; i < new_permutation.size(); i++)
    {
        for (int j = 0; j < assignments.size(); j++)
        {
            if (new_permutation[j]==assignments[i])
            {
                swarm[p].permutation[i] = j+1;
            }   
        }
    }

    /* Evaluate particle */
    Strip s = {};
    s.height = max_height;
    s.width = strip_width;

    s.x_position = 0;
    s.y_position = 0;

    HR(items,s,n_items,swarm[p]); 


    /* Update personal best */
    if (swarm[p].fitness < swarm[p].pbest_fitness)
    {
        swarm[p].pbest = swarm[p].permutation;
        swarm[p].pbest_fitness = swarm[p].fitness;
    }

    
    /* Update global best, using mutex */

    if (swarm[p].pbest_fitness < gbest.fitness)
    {
        pthread_mutex_lock(&mutex);
        gbest.fitness = swarm[p].pbest_fitness;
        gbest.permutation = swarm[p].pbest;
        pthread_mutex_unlock (&mutex);
    } 

    pthread_exit((void*) 0);   

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x2758, %rsp           # imm = 0x2758
movq %rdi, %rbx
leaq -0x2770(%rbp), %r14
movq %r14, %rdi
callq 0x3c16
movq %r14, %rdi
callq 0x2230
movl %eax, %eax
movq %rax, -0x13e8(%rbp)
movl $0x1, %ecx
movq %rax, %rdx
shrq $0x1e, %rdx
xorl %eax, %edx
imull $0x6c078965, %edx, %eax # imm = 0x6C078965
addl %ecx, %eax
movq %rax, -0x13e8(%rbp,%rcx,8)
incq %rcx
cmpq $0x270, %rcx            # imm = 0x270
jne 0x323b
movq $0x270, -0x68(%rbp)     # imm = 0x270
movslq 0x70f9(%rip), %rsi      # 0xa368
leaq -0x30(%rbp), %rdi
leaq -0x48(%rbp), %rdx
callq 0x41a4
movq -0x30(%rbp), %rax
movq -0x28(%rbp), %rcx
cmpq %rcx, %rax
je 0x32a4
movl $0x1, %edx
xorps %xmm0, %xmm0
cvtsi2ss %edx, %xmm0
movss %xmm0, (%rax)
incl %edx
addq $0x4, %rax
cmpq %rcx, %rax
jne 0x328e
movq 0x6f85(%rip), %rax      # 0xa230
imulq $0x58, %rbx, %r14
movq 0x8(%rax,%r14), %rcx
cmpq (%rax,%r14), %rcx
je 0x33b9
xorl %r15d, %r15d
leaq -0x13e8(%rbp), %rbx
movq %rbx, %rdi
callq 0x5462
movsd %xmm0, -0x50(%rbp)
movq %rbx, %rdi
callq 0x5462
xorpd %xmm1, %xmm1
movsd -0x50(%rbp), %xmm3
addsd %xmm1, %xmm3
movq 0x6f3f(%rip), %rax      # 0xa230
movq (%rax,%r14), %rcx
movq 0x20(%rax,%r14), %rdx
movl (%rdx,%r15,4), %edx
movl (%rcx,%r15,4), %ecx
subl %ecx, %edx
xorps %xmm2, %xmm2
cvtsi2ss %edx, %xmm2
cvtsd2ss %xmm3, %xmm3
movq 0x6ec2(%rip), %rdx      # 0xa1d8
movl (%rdx,%r15,4), %edx
subl %ecx, %edx
xorps %xmm4, %xmm4
cvtsi2ss %edx, %xmm4
addsd %xmm1, %xmm0
xorps %xmm1, %xmm1
cvtsi2ss %ecx, %xmm1
cvtsd2ss %xmm0, %xmm0
mulss 0x7036(%rip), %xmm3     # 0xa370
mulss %xmm2, %xmm3
movss 0x7026(%rip), %xmm2     # 0xa36c
mulss %xmm1, %xmm2
addss %xmm3, %xmm2
mulss 0x701e(%rip), %xmm0     # 0xa374
mulss %xmm4, %xmm0
addss %xmm2, %xmm0
movss 0x701e(%rip), %xmm2     # 0xa384
ucomiss %xmm0, %xmm2
ja 0x337e
movss 0x700d(%rip), %xmm3     # 0xa380
ucomiss %xmm3, %xmm0
movaps %xmm0, %xmm2
jbe 0x337e
movaps %xmm3, %xmm2
addq %r14, %rax
movq 0x40(%rax), %rax
movss %xmm2, (%rax,%r15,4)
addss %xmm2, %xmm1
movq -0x30(%rbp), %rax
movss %xmm1, (%rax,%r15,4)
incq %r15
movq 0x6e8d(%rip), %rax      # 0xa230
movq 0x8(%rax,%r14), %rcx
subq (%rax,%r14), %rcx
sarq $0x2, %rcx
cmpq %r15, %rcx
ja 0x32c8
leaq -0x48(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x4238
movq -0x48(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x42b8
movq -0x30(%rbp), %rax
movq -0x28(%rbp), %rcx
subq %rax, %rcx
je 0x3449
sarq $0x2, %rcx
movq -0x48(%rbp), %rdx
movq -0x40(%rbp), %rsi
movq %rsi, %rdi
subq %rdx, %rdi
sarq $0x2, %rdi
cmpq $0x1, %rdi
adcq $0x0, %rdi
cmpq $0x1, %rcx
adcq $0x0, %rcx
xorl %r8d, %r8d
cmpq %rdx, %rsi
je 0x3441
movss (%rdx,%r8,4), %xmm0
movq 0x6e15(%rip), %r9       # 0xa230
addq %r14, %r9
xorl %r10d, %r10d
movss (%rax,%r10,4), %xmm1
ucomiss %xmm0, %xmm1
jne 0x3439
jp 0x3439
movq (%r9), %r11
leal 0x1(%r10), %ebx
movl %ebx, (%r11,%r8,4)
incq %r10
cmpq %r10, %rdi
jne 0x3421
incq %r8
cmpq %rcx, %r8
jne 0x3409
xorps %xmm0, %xmm0
leaq -0x60(%rbp), %rsi
movaps %xmm0, (%rsi)
movl 0x6f33(%rip), %eax      # 0xa38c
movl %eax, (%rsi)
movl 0x6f27(%rip), %eax      # 0xa388
movl %eax, 0x4(%rsi)
movq $0x0, 0x8(%rsi)
movq 0x6dbd(%rip), %rcx      # 0xa230
addq %r14, %rcx
leaq 0x6f13(%rip), %rdi      # 0xa390
callq 0x2d6d
movq 0x6da7(%rip), %rsi      # 0xa230
movl 0x18(%rsi,%r14), %eax
cmpl 0x38(%rsi,%r14), %eax
jge 0x34b2
addq %r14, %rsi
leaq 0x20(%rsi), %rdi
callq 0x3ea0
movq 0x6d88(%rip), %rax      # 0xa230
movl 0x18(%rax,%r14), %ecx
movl %ecx, 0x38(%rax,%r14)
movq 0x6d77(%rip), %rax      # 0xa230
movl 0x38(%rax,%r14), %eax
cmpl 0x6d2c(%rip), %eax      # 0xa1f0
jge 0x3502
leaq 0x6e73(%rip), %rdi      # 0xa340
callq 0x2250
movq 0x6d57(%rip), %rax      # 0xa230
leaq (%rax,%r14), %rsi
addq $0x20, %rsi
movl 0x18(%rsi), %eax
movl %eax, 0x6d06(%rip)      # 0xa1f0
leaq 0x6ce7(%rip), %rdi      # 0xa1d8
callq 0x3ea0
leaq 0x6e43(%rip), %rdi      # 0xa340
callq 0x2140
xorl %edi, %edi
callq 0x2300
jmp 0x350b
movq %rax, %rbx
movq -0x48(%rbp), %rdi
testq %rdi, %rdi
je 0x352c
movq -0x38(%rbp), %rsi
subq %rdi, %rsi
callq 0x21c0
jmp 0x352c
jmp 0x3529
jmp 0x3529
movq %rax, %rbx
movq -0x30(%rbp), %rdi
testq %rdi, %rdi
je 0x3548
movq -0x20(%rbp), %rsi
subq %rdi, %rsi
callq 0x21c0
jmp 0x3548
jmp 0x3545
movq %rax, %rbx
leaq -0x2770(%rbp), %rdi
callq 0x2190
movq %rbx, %rdi
callq 0x22f0
movq %rax, %rdi
callq 0x442a