// File: /workspace/github_cpp_makefile_star2_O3/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 0x3c00
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 0x3256
movq $0x270, -0x68(%rbp)     # imm = 0x270
movslq 0x70de(%rip), %rsi      # 0xa368
leaq -0x30(%rbp), %rdi
leaq -0x48(%rbp), %rdx
callq 0x41ac
movq -0x30(%rbp), %rax
movq -0x28(%rbp), %rcx
cmpq %rcx, %rax
je 0x32bf
movl $0x1, %edx
xorps %xmm0, %xmm0
cvtsi2ss %edx, %xmm0
movss %xmm0, (%rax)
incl %edx
addq $0x4, %rax
cmpq %rcx, %rax
jne 0x32a9
movq 0x6f6a(%rip), %rax      # 0xa230
imulq $0x58, %rbx, %r14
movq 0x8(%rax,%r14), %rcx
cmpq (%rax,%r14), %rcx
je 0x33cb
xorl %r15d, %r15d
leaq -0x13e8(%rbp), %rbx
movq %rbx, %rdi
callq 0x5450
movsd %xmm0, -0x50(%rbp)
movq %rbx, %rdi
callq 0x5450
xorpd %xmm1, %xmm1
movsd -0x50(%rbp), %xmm3
addsd %xmm1, %xmm3
movq 0x6f24(%rip), %rcx      # 0xa230
movq (%rcx,%r14), %rax
movq 0x20(%rcx,%r14), %rdx
movl (%rdx,%r15,4), %edx
movl (%rax,%r15,4), %esi
subl %esi, %edx
xorps %xmm2, %xmm2
cvtsi2ss %edx, %xmm2
cvtsd2ss %xmm3, %xmm3
movq 0x6ea7(%rip), %rdx      # 0xa1d8
movl (%rdx,%r15,4), %edx
subl %esi, %edx
xorps %xmm4, %xmm4
cvtsi2ss %edx, %xmm4
addsd %xmm1, %xmm0
xorps %xmm1, %xmm1
cvtsi2ss %esi, %xmm1
cvtsd2ss %xmm0, %xmm0
mulss 0x701b(%rip), %xmm3     # 0xa370
mulss %xmm2, %xmm3
movss 0x700b(%rip), %xmm2     # 0xa36c
mulss %xmm1, %xmm2
addss %xmm3, %xmm2
mulss 0x7003(%rip), %xmm0     # 0xa374
mulss %xmm4, %xmm0
addss %xmm2, %xmm0
movss 0x7003(%rip), %xmm2     # 0xa384
ucomiss %xmm0, %xmm2
ja 0x3399
movss 0x6ff2(%rip), %xmm3     # 0xa380
ucomiss %xmm3, %xmm0
movaps %xmm0, %xmm2
jbe 0x3399
movaps %xmm3, %xmm2
addq %r14, %rcx
movq 0x40(%rcx), %rdx
movss %xmm2, (%rdx,%r15,4)
addss %xmm2, %xmm1
movq -0x30(%rbp), %rdx
movss %xmm1, (%rdx,%r15,4)
incq %r15
movq 0x8(%rcx), %rcx
subq %rax, %rcx
sarq $0x2, %rcx
cmpq %r15, %rcx
ja 0x32e3
leaq -0x48(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x4242
movq -0x48(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x42c2
movq -0x30(%rbp), %rax
movq -0x28(%rbp), %rcx
subq %rax, %rcx
je 0x345b
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 0x3453
movss (%rdx,%r8,4), %xmm0
movq 0x6e03(%rip), %r9       # 0xa230
addq %r14, %r9
xorl %r10d, %r10d
movss (%rax,%r10,4), %xmm1
ucomiss %xmm0, %xmm1
jne 0x344b
jp 0x344b
movq (%r9), %r11
leal 0x1(%r10), %ebx
movl %ebx, (%r11,%r8,4)
incq %r10
cmpq %r10, %rdi
jne 0x3433
incq %r8
cmpq %rcx, %r8
jne 0x341b
movl 0x6f2b(%rip), %eax      # 0xa38c
leaq -0x60(%rbp), %rsi
movl %eax, (%rsi)
movl 0x6f1b(%rip), %eax      # 0xa388
movl %eax, 0x4(%rsi)
movq $0x0, 0x8(%rsi)
movq 0x6db1(%rip), %rcx      # 0xa230
addq %r14, %rcx
leaq 0x6f07(%rip), %rdi      # 0xa390
callq 0x2d7e
movq 0x6d9b(%rip), %rsi      # 0xa230
movl 0x18(%rsi,%r14), %eax
cmpl 0x38(%rsi,%r14), %eax
jge 0x34be
addq %r14, %rsi
leaq 0x20(%rsi), %rdi
callq 0x3e8c
movq 0x6d7c(%rip), %rsi      # 0xa230
movl 0x18(%rsi,%r14), %eax
movl %eax, 0x38(%rsi,%r14)
movl 0x38(%rsi,%r14), %eax
cmpl 0x6d27(%rip), %eax      # 0xa1f0
jge 0x3507
leaq 0x6e6e(%rip), %rdi      # 0xa340
callq 0x2250
movq 0x6d52(%rip), %rax      # 0xa230
leaq (%rax,%r14), %rsi
addq $0x20, %rsi
movl 0x18(%rsi), %eax
movl %eax, 0x6d01(%rip)      # 0xa1f0
leaq 0x6ce2(%rip), %rdi      # 0xa1d8
callq 0x3e8c
leaq 0x6e3e(%rip), %rdi      # 0xa340
callq 0x2140
xorl %edi, %edi
callq 0x2300
jmp 0x3510
movq %rax, %rbx
movq -0x48(%rbp), %rdi
testq %rdi, %rdi
je 0x3531
movq -0x38(%rbp), %rsi
subq %rdi, %rsi
callq 0x21c0
jmp 0x3531
jmp 0x352e
jmp 0x352e
movq %rax, %rbx
movq -0x30(%rbp), %rdi
testq %rdi, %rdi
je 0x354d
movq -0x20(%rbp), %rsi
subq %rdi, %rsi
callq 0x21c0
jmp 0x354d
jmp 0x354a
movq %rax, %rbx
leaq -0x2770(%rbp), %rdi
callq 0x2190
movq %rbx, %rdi
callq 0x22f0
movq %rax, %rdi
callq 0x4434