// File: 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
subq $0x2880, %rsp           # imm = 0x2880
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x10(%rbp)
leaq -0x1398(%rbp), %rdi
movq %rdi, -0x27e0(%rbp)
callq 0x4a50
movq -0x27e0(%rbp), %rdi
callq 0x4af0
movl %eax, -0x27d4(%rbp)
jmp 0x372e
movl -0x27d4(%rbp), %eax
movl %eax, %eax
movl %eax, %esi
leaq -0x2720(%rbp), %rdi
callq 0x4b10
jmp 0x3746
leaq -0x2740(%rbp), %rdi
xorps %xmm0, %xmm0
movsd 0xc8b0(%rip), %xmm1     # 0x10008
callq 0x5900
jmp 0x375f
movslq 0x14c62(%rip), %rax     # 0x183c8
movq %rax, -0x27f0(%rbp)
leaq -0x2759(%rbp), %rdi
movq %rdi, -0x27e8(%rbp)
callq 0x5170
movq -0x27f0(%rbp), %rsi
movq -0x27e8(%rbp), %rdx
leaq -0x2758(%rbp), %rdi
callq 0x5930
jmp 0x379c
leaq -0x2759(%rbp), %rdi
callq 0x5210
leaq -0x2758(%rbp), %rdi
callq 0x5a00
movq %rax, -0x27f8(%rbp)
jmp 0x37bd
movq -0x27f8(%rbp), %rax
movq %rax, -0x2768(%rbp)
leaq -0x2758(%rbp), %rdi
callq 0x5a30
movq %rax, -0x2800(%rbp)
jmp 0x37e0
movq -0x2800(%rbp), %rax
movq %rax, -0x2770(%rbp)
movq -0x2768(%rbp), %rdi
movq -0x2770(%rbp), %rsi
movl $0x1, %edx
callq 0x59a0
jmp 0x3808
movl $0x0, -0x2774(%rbp)
movslq -0x2774(%rbp), %rax
movq %rax, -0x2808(%rbp)
movq -0x10(%rbp), %rsi
leaq 0x14a65(%rip), %rdi     # 0x18290
callq 0x58e0
movq %rax, %rdi
callq 0x55e0
movq %rax, %rcx
movq -0x2808(%rbp), %rax
cmpq %rcx, %rax
jae 0x3b51
leaq -0x2740(%rbp), %rdi
leaq -0x2720(%rbp), %rsi
callq 0x5a60
movsd %xmm0, -0x2810(%rbp)
jmp 0x3868
movsd -0x2810(%rbp), %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x2778(%rbp)
leaq -0x2740(%rbp), %rdi
leaq -0x2720(%rbp), %rsi
callq 0x5a60
movsd %xmm0, -0x2818(%rbp)
jmp 0x3899
movsd -0x2818(%rbp), %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x277c(%rbp)
movq -0x10(%rbp), %rsi
leaq 0x149d8(%rip), %rdi     # 0x18290
callq 0x58e0
movq %rax, %rdi
addq $0x20, %rdi
movslq -0x2774(%rbp), %rsi
callq 0x5600
movl (%rax), %eax
movl %eax, -0x2824(%rbp)
movq -0x10(%rbp), %rsi
leaq 0x149ad(%rip), %rdi     # 0x18290
callq 0x58e0
movq %rax, %rdi
movslq -0x2774(%rbp), %rsi
callq 0x5600
movq %rax, %rcx
movl -0x2824(%rbp), %eax
subl (%rcx), %eax
cvtsi2ss %eax, %xmm0
movss %xmm0, -0x2780(%rbp)
movslq -0x2774(%rbp), %rsi
leaq 0x1491c(%rip), %rdi     # 0x18238
callq 0x5600
movl (%rax), %eax
movl %eax, -0x2820(%rbp)
movq -0x10(%rbp), %rsi
leaq 0x1495c(%rip), %rdi     # 0x18290
callq 0x58e0
movq %rax, %rdi
movslq -0x2774(%rbp), %rsi
callq 0x5600
movq %rax, %rcx
movl -0x2820(%rbp), %eax
subl (%rcx), %eax
cvtsi2ss %eax, %xmm0
movss %xmm0, -0x2784(%rbp)
movss 0x14a65(%rip), %xmm0    # 0x183cc
movss %xmm0, -0x281c(%rbp)
movq -0x10(%rbp), %rsi
leaq 0x14916(%rip), %rdi     # 0x18290
callq 0x58e0
movq %rax, %rdi
movslq -0x2774(%rbp), %rsi
callq 0x5600
movss -0x281c(%rbp), %xmm1
cvtsi2ssl (%rax), %xmm2
movss -0x2778(%rbp), %xmm0
mulss 0x14a26(%rip), %xmm0    # 0x183d0
mulss -0x2780(%rbp), %xmm0
mulss %xmm2, %xmm1
addss %xmm0, %xmm1
movss -0x277c(%rbp), %xmm0
mulss 0x14a0a(%rip), %xmm0    # 0x183d4
movss -0x2784(%rbp), %xmm2
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, -0x2788(%rbp)
movss -0x2788(%rbp), %xmm1
movss 0x149f2(%rip), %xmm0    # 0x183e4
ucomiss %xmm1, %xmm0
jbe 0x3a5a
movss 0x149e5(%rip), %xmm0    # 0x183e4
movss %xmm0, -0x2788(%rbp)
jmp 0x3a7d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x2728(%rbp)
movl %eax, -0x272c(%rbp)
jmp 0x3e97
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x2728(%rbp)
movl %eax, -0x272c(%rbp)
leaq -0x2759(%rbp), %rdi
callq 0x5210
jmp 0x3e97
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x2728(%rbp)
movl %eax, -0x272c(%rbp)
jmp 0x3e8b
movss -0x2788(%rbp), %xmm0
ucomiss 0x14977(%rip), %xmm0    # 0x183e0
jbe 0x3a7b
movss 0x1496d(%rip), %xmm0    # 0x183e0
movss %xmm0, -0x2788(%rbp)
jmp 0x3a7d
movss -0x2788(%rbp), %xmm0
movss %xmm0, -0x2830(%rbp)
movq -0x10(%rbp), %rsi
leaq 0x147f8(%rip), %rdi     # 0x18290
callq 0x58e0
movq %rax, %rdi
addq $0x40, %rdi
movslq -0x2774(%rbp), %rsi
callq 0x5640
movss -0x2830(%rbp), %xmm0
movss %xmm0, (%rax)
movq -0x10(%rbp), %rsi
leaq 0x147c9(%rip), %rdi     # 0x18290
callq 0x58e0
movq %rax, %rdi
movslq -0x2774(%rbp), %rsi
callq 0x5600
cvtsi2ssl (%rax), %xmm0
movss %xmm0, -0x282c(%rbp)
movq -0x10(%rbp), %rsi
leaq 0x1479e(%rip), %rdi     # 0x18290
callq 0x58e0
movq %rax, %rdi
addq $0x40, %rdi
movslq -0x2774(%rbp), %rsi
callq 0x5640
movss -0x282c(%rbp), %xmm0
addss (%rax), %xmm0
movss %xmm0, -0x2828(%rbp)
movslq -0x2774(%rbp), %rsi
leaq -0x2758(%rbp), %rdi
callq 0x5640
movss -0x2828(%rbp), %xmm0
movss %xmm0, (%rax)
movl -0x2774(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2774(%rbp)
jmp 0x3812
leaq -0x27a0(%rbp), %rdi
leaq -0x2758(%rbp), %rsi
callq 0x5a90
jmp 0x3b66
leaq -0x27a0(%rbp), %rdi
movq %rdi, -0x2838(%rbp)
callq 0x5bc0
movq -0x2838(%rbp), %rdi
movq %rax, -0x27a8(%rbp)
callq 0x5bf0
movq %rax, -0x27b0(%rbp)
movq -0x27a8(%rbp), %rdi
movq -0x27b0(%rbp), %rsi
callq 0x5b80
jmp 0x3ba8
movl $0x0, -0x27b4(%rbp)
movslq -0x27b4(%rbp), %rax
movq %rax, -0x2840(%rbp)
leaq -0x2758(%rbp), %rdi
callq 0x5620
movq %rax, %rcx
movq -0x2840(%rbp), %rax
cmpq %rcx, %rax
jae 0x3cde
movl $0x0, -0x27b8(%rbp)
movslq -0x27b8(%rbp), %rax
movq %rax, -0x2848(%rbp)
leaq -0x27a0(%rbp), %rdi
callq 0x5620
movq %rax, %rcx
movq -0x2848(%rbp), %rax
cmpq %rcx, %rax
jae 0x3cc8
movslq -0x27b8(%rbp), %rsi
leaq -0x2758(%rbp), %rdi
callq 0x5640
movss (%rax), %xmm0
movss %xmm0, -0x284c(%rbp)
movslq -0x27b4(%rbp), %rsi
leaq -0x27a0(%rbp), %rdi
callq 0x5640
movss -0x284c(%rbp), %xmm0
ucomiss (%rax), %xmm0
jne 0x3cb2
jp 0x3cb2
movl -0x27b8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2850(%rbp)
movq -0x10(%rbp), %rsi
leaq 0x1461f(%rip), %rdi     # 0x18290
callq 0x58e0
movq %rax, %rdi
movslq -0x27b4(%rbp), %rsi
callq 0x5600
movl -0x2850(%rbp), %ecx
movl %ecx, (%rax)
jmp 0x3cb2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x2728(%rbp)
movl %eax, -0x272c(%rbp)
leaq -0x27a0(%rbp), %rdi
callq 0x54f0
jmp 0x3e8b
jmp 0x3cb4
movl -0x27b8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x27b8(%rbp)
jmp 0x3be9
jmp 0x3cca
movl -0x27b4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x27b4(%rbp)
jmp 0x3bb2
xorps %xmm0, %xmm0
movaps %xmm0, -0x27d0(%rbp)
movl 0x146fe(%rip), %eax     # 0x183ec
movl %eax, -0x27d0(%rbp)
movl 0x146ee(%rip), %eax     # 0x183e8
movl %eax, -0x27cc(%rbp)
movl $0x0, -0x27c8(%rbp)
movl $0x0, -0x27c4(%rbp)
movl 0x146ae(%rip), %eax     # 0x183c8
movl %eax, -0x2854(%rbp)
movq -0x10(%rbp), %rsi
leaq 0x14565(%rip), %rdi     # 0x18290
callq 0x58e0
movl -0x2854(%rbp), %edx
movq %rax, %rcx
leaq 0x146b0(%rip), %rdi     # 0x183f0
leaq -0x27d0(%rbp), %rsi
callq 0x30c0
jmp 0x3d4e
movq -0x10(%rbp), %rsi
leaq 0x14537(%rip), %rdi     # 0x18290
callq 0x58e0
movl 0x18(%rax), %eax
movl %eax, -0x2858(%rbp)
movq -0x10(%rbp), %rsi
leaq 0x1451e(%rip), %rdi     # 0x18290
callq 0x58e0
movq %rax, %rcx
movl -0x2858(%rbp), %eax
cmpl 0x38(%rcx), %eax
jge 0x3dfa
movq -0x10(%rbp), %rsi
leaq 0x14500(%rip), %rdi     # 0x18290
movq %rdi, -0x2868(%rbp)
callq 0x58e0
movq -0x2868(%rbp), %rdi
movq %rax, -0x2860(%rbp)
movq -0x10(%rbp), %rsi
callq 0x58e0
movq -0x2860(%rbp), %rsi
movq %rax, %rdi
addq $0x20, %rdi
callq 0x4f20
jmp 0x3dc8
movq -0x10(%rbp), %rsi
leaq 0x144bd(%rip), %rdi     # 0x18290
callq 0x58e0
movl 0x18(%rax), %eax
movl %eax, -0x286c(%rbp)
movq -0x10(%rbp), %rsi
leaq 0x144a4(%rip), %rdi     # 0x18290
callq 0x58e0
movl -0x286c(%rbp), %ecx
movl %ecx, 0x38(%rax)
movq -0x10(%rbp), %rsi
leaq 0x1448b(%rip), %rdi     # 0x18290
callq 0x58e0
movl 0x38(%rax), %eax
cmpl 0x1443d(%rip), %eax     # 0x18250
jge 0x3e80
leaq 0x14584(%rip), %rdi     # 0x183a0
callq 0x22e0
movq -0x10(%rbp), %rsi
leaq 0x14464(%rip), %rdi     # 0x18290
movq %rdi, -0x2880(%rbp)
callq 0x58e0
movq -0x2880(%rbp), %rdi
movl 0x38(%rax), %eax
movl %eax, 0x14408(%rip)     # 0x18250
leaq 0x143e9(%rip), %rax     # 0x18238
movq %rax, -0x2878(%rbp)
movq -0x10(%rbp), %rsi
callq 0x58e0
movq -0x2878(%rbp), %rdi
movq %rax, %rsi
addq $0x20, %rsi
callq 0x4f20
jmp 0x3e74
leaq 0x14525(%rip), %rdi     # 0x183a0
callq 0x2150
xorl %eax, %eax
movl %eax, %edi
callq 0x2390
jmp 0x3e8b
leaq -0x2758(%rbp), %rdi
callq 0x54f0
leaq -0x1398(%rbp), %rdi
callq 0x55b0
movq -0x2728(%rbp), %rdi
callq 0x2380
nop