// File: flastest[P]HeterogeneousParallelDijkstra/dijkstra_cond_var.cc
// Function: relax_vertex(unsigned long, unsigned long, float, std::priority_queue<std::pair<unsigned long, float>, std::vector<std::pair<unsigned long, float>, std::allocator<std::pair<unsigned long, float>>>, Offer_Comparator>&, std::map<unsigned long, std::shared_ptr<std::mutex>, std::less<unsigned long>, std::allocator<std::pair<unsigned long const, std::shared_ptr<std::mutex>>>>, std::map<unsigned long, float, std::less<unsigned long>, std::allocator<std::pair<unsigned long const, float>>>&, std::map<unsigned long, std::shared_ptr<std::mutex>, std::less<unsigned long>, std::allocator<std::pair<unsigned long const, std::shared_ptr<std::mutex>>>>&, std::map<unsigned long, unsigned long, std::less<unsigned long>, std::allocator<std::pair<unsigned long const, unsigned long>>>&, int)
void relax_vertex(vertex_descriptor neighbor, 
			vertex_descriptor origin,
		   float vd,
		   offer_pqueue_t& offer_pq, 
		   mutex_map_t distance_mutexes,
		   distance_map_t& distances,
		   mutex_map_t& predecessor_mutexes,
		   predecessor_map_t& predecessors,
		   int thread_id )
{
	std::lock_guard<std::mutex> guard(*distance_mutexes[neighbor]);
	if (vd < distances[neighbor]) 
	{

		{
			//condition variable now gets to release a thread!
			
			
			//if (DEBUG_THREAD) print_thread_debug(thread_id, "ADDING AN OFFER TO " + std::to_string(neighbor) + "!!! distnace is " + std::to_string(vd) , debug_file_stream);
			std::scoped_lock<std::mutex> guard2(pq_mutex);
			offer_pq.push(offer_t(neighbor,vd));
			
			//if (DEBUG_THREAD) print_thread_debug(thread_id, "updating "+ std::to_string(neighbor) +"'s predecessor", debug_file_stream);
			std::scoped_lock<std::mutex> guard(*predecessor_mutexes[neighbor]);
			//now update this node's predecessor 
			predecessors[neighbor] = origin;
			//if(DEBUG_THREAD) print_thread_debug(thread_id, "now done relaxing!", debug_file_stream);
			cond_var_offer_pq.notify_all();
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rcx, -0x90(%rbp)
movq %rdi, %rax
movq -0x90(%rbp), %rdi
movl 0x18(%rbp), %ecx
movq 0x10(%rbp), %rcx
movq %rax, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movss %xmm0, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movq %rdi, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movq %r9, -0x38(%rbp)
leaq -0x8(%rbp), %rsi
movq %rsi, -0x88(%rbp)
callq 0x1d470
movq %rax, %rdi
callq 0x1d550
movq %rax, %rsi
leaq -0x40(%rbp), %rdi
callq 0x1d580
movq -0x88(%rbp), %rsi
movss -0x14(%rbp), %xmm0
movss %xmm0, -0x7c(%rbp)
movq -0x30(%rbp), %rdi
callq 0x1d5b0
movq %rax, -0x78(%rbp)
jmp 0x1c3c4
movss -0x7c(%rbp), %xmm1
movq -0x78(%rbp), %rax
movss (%rax), %xmm0
ucomiss %xmm1, %xmm0
jbe 0x1c4da
leaq 0x1ef87(%rip), %rsi     # 0x3b368
leaq -0x58(%rbp), %rdi
callq 0x1d690
jmp 0x1c3ec
movq -0x20(%rbp), %rax
movq %rax, -0x98(%rbp)
leaq -0x68(%rbp), %rdi
leaq -0x8(%rbp), %rsi
leaq -0x14(%rbp), %rdx
callq 0x1d710
jmp 0x1c40a
movq -0x98(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x1d6c0
jmp 0x1c41c
movq -0x38(%rbp), %rdi
leaq -0x8(%rbp), %rsi
callq 0x1d470
movq %rax, -0xa0(%rbp)
jmp 0x1c432
movq -0xa0(%rbp), %rdi
callq 0x1d550
movq %rax, %rsi
leaq -0x70(%rbp), %rdi
callq 0x1d690
jmp 0x1c44c
movq -0x10(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq 0x10(%rbp), %rdi
leaq -0x8(%rbp), %rsi
callq 0x1d740
movq %rax, -0xa8(%rbp)
jmp 0x1c46d
movq -0xa8(%rbp), %rax
movq -0xb0(%rbp), %rcx
movq %rcx, (%rax)
leaq 0x1ef5b(%rip), %rdi     # 0x3b3e0
callq 0x4540
leaq -0x70(%rbp), %rdi
callq 0x1d820
leaq -0x58(%rbp), %rdi
callq 0x1d820
jmp 0x1c4da
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x1c4ec
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x1c4cf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x1d820
leaq -0x58(%rbp), %rdi
callq 0x1d820
jmp 0x1c4ec
leaq -0x40(%rbp), %rdi
callq 0x1d850
addq $0xb0, %rsp
popq %rbp
retq
leaq -0x40(%rbp), %rdi
callq 0x1d850
movq -0x48(%rbp), %rdi
callq 0x4580
nop