// File: flordan[P]ipc_benchmark/sysv_mq/producer.cpp
// Function: main
int main(int argc, char *argv[])
{
    std::cout << "Producer running" << std::endl;
    int pid = getpid();
    std::cout << "Producer PID " << pid << std::endl;

    int mq_producer, mq_consumer;
    if ((mq_producer = msgget (IPC_PRIVATE, 0660)) == -1) {
        std::cerr << "Cannot get queue for producer." << std::endl;
        return 1;
    }

    char *key_path=argv[1];
    char *consumer_pid = argv[2];
    
    std::cout << "Synchronizing with consumer key_path " << key_path << " project " << consumer_pid << std::endl;
    key_t msg_queue_key;
    if ((msg_queue_key = ftok (key_path, std::atoi(consumer_pid))) == -1) {
        std::cerr << "Cannot get key for file " << key_path <<" and project " << consumer_pid << std::endl;
         return 1;
    }
    if ((mq_consumer = msgget (msg_queue_key, 0)) == -1) {
        std::cerr << "Cannot get consumer queue." << std::endl;
        return 1;
    }
    else
    {
        std::cout << "Obtained consumer queue." << std::endl;
    }

    struct message_text out_message;
    out_message.reply_to = mq_producer;
    if (msgsnd (mq_consumer, &out_message, sizeof (struct message_text), 0) == -1) {
            std::cerr << "Not able to send message to consumer" << std::endl;
            return 1;
    }
    std::cout<<"Waiting for consumer ACK on queue " << mq_producer <<"."<<std::endl;

    struct message_text in_message;
    if (msgrcv (mq_producer,  &in_message, sizeof (struct message_text), 0, 0) == -1) {
            std::cerr << "Cannot read from producer queue."  << std::endl;
            return 1;
    }

    std::cout << "Synchronized" << std::endl;

    std::cout << "Latency test" << std::endl;    
    struct timeval st;
    for (int i = 0; i < LATENCY_PROBES; i++)
    {
        gettimeofday(&st, NULL);
        std::ostringstream os ;
        os << st.tv_sec << "." << st.tv_usec+1000000;
        std::string mystr = os.str();
        const char* time = mystr.c_str();
        strcpy(out_message.message, time);
        msgsnd (mq_consumer, &out_message, sizeof (struct message_text), 0);
        usleep(250000);
    }

    std::cout << "Finished" << std::endl;
}

// Assembly:
subq $0x3b8, %rsp            # imm = 0x3B8
movl $0x0, 0x3b4(%rsp)
movl %edi, 0x3b0(%rsp)
movq %rsi, 0x3a8(%rsp)
movq 0x2ce8(%rip), %rdi      # 0x3fd0
leaq 0xd15(%rip), %rsi       # 0x2004
callq 0x10b0
movq %rax, %rdi
movq 0x2cc2(%rip), %rsi      # 0x3fc0
callq 0x10d0
callq 0x1100
movl %eax, 0x3a4(%rsp)
movq 0x2cba(%rip), %rdi      # 0x3fd0
leaq 0xcf8(%rip), %rsi       # 0x2015
callq 0x10b0
movq %rax, %rdi
movl 0x3a4(%rsp), %esi
callq 0x1150
movq %rax, %rdi
movq 0x2c85(%rip), %rsi      # 0x3fc0
callq 0x10d0
xorl %edi, %edi
movl $0x1b0, %esi            # imm = 0x1B0
callq 0x1080
movl %eax, 0x3a0(%rsp)
cmpl $-0x1, %eax
jne 0x138a
movq 0x2c91(%rip), %rdi      # 0x3ff0
leaq 0xcbd(%rip), %rsi       # 0x2023
callq 0x10b0
movq %rax, %rdi
movq 0x2c4b(%rip), %rsi      # 0x3fc0
callq 0x10d0
movl $0x1, 0x3b4(%rsp)
jmp 0x17a1
movq 0x3a8(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x390(%rsp)
movq 0x3a8(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x388(%rsp)
movq 0x2c17(%rip), %rdi      # 0x3fd0
leaq 0xc82(%rip), %rsi       # 0x2042
callq 0x10b0
movq %rax, %rdi
movq 0x390(%rsp), %rsi
callq 0x10b0
movq %rax, %rdi
leaq 0xca6(%rip), %rsi       # 0x2085
callq 0x10b0
movq %rax, %rdi
movq 0x388(%rsp), %rsi
callq 0x10b0
movq %rax, %rdi
movq 0x2bc2(%rip), %rsi      # 0x3fc0
callq 0x10d0
movq 0x390(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x388(%rsp), %rdi
callq 0x1120
movq 0x18(%rsp), %rdi
movl %eax, %esi
callq 0x1130
movl %eax, 0x384(%rsp)
cmpl $-0x1, %eax
jne 0x1496
movq 0x2bb4(%rip), %rdi      # 0x3ff0
leaq 0xc25(%rip), %rsi       # 0x2068
callq 0x10b0
movq %rax, %rdi
movq 0x390(%rsp), %rsi
callq 0x10b0
movq %rax, %rdi
leaq 0xc1f(%rip), %rsi       # 0x2081
callq 0x10b0
movq %rax, %rdi
movq 0x388(%rsp), %rsi
callq 0x10b0
movq %rax, %rdi
movq 0x2b3f(%rip), %rsi      # 0x3fc0
callq 0x10d0
movl $0x1, 0x3b4(%rsp)
jmp 0x17a1
movl 0x384(%rsp), %edi
xorl %esi, %esi
callq 0x1080
movl %eax, 0x39c(%rsp)
cmpl $-0x1, %eax
jne 0x14e2
movq 0x2b39(%rip), %rdi      # 0x3ff0
leaq 0xbd1(%rip), %rsi       # 0x208f
callq 0x10b0
movq %rax, %rdi
movq 0x2af3(%rip), %rsi      # 0x3fc0
callq 0x10d0
movl $0x1, 0x3b4(%rsp)
jmp 0x17a1
movq 0x2ae7(%rip), %rdi      # 0x3fd0
leaq 0xbba(%rip), %rsi       # 0x20aa
callq 0x10b0
movq %rax, %rdi
movq 0x2ac1(%rip), %rsi      # 0x3fc0
callq 0x10d0
movl 0x3a0(%rsp), %eax
movl %eax, 0x2b8(%rsp)
movl 0x39c(%rsp), %edi
leaq 0x2b8(%rsp), %rsi
movl $0xcc, %edx
xorl %ecx, %ecx
callq 0x1070
cmpl $-0x1, %eax
jne 0x1564
movq 0x2ab7(%rip), %rdi      # 0x3ff0
leaq 0xb83(%rip), %rsi       # 0x20c3
callq 0x10b0
movq %rax, %rdi
movq 0x2a71(%rip), %rsi      # 0x3fc0
callq 0x10d0
movl $0x1, 0x3b4(%rsp)
jmp 0x17a1
movq 0x2a65(%rip), %rdi      # 0x3fd0
leaq 0xb76(%rip), %rsi       # 0x20e8
callq 0x10b0
movq %rax, %rdi
movl 0x3a0(%rsp), %esi
callq 0x1150
movq %rax, %rdi
leaq 0xb9a(%rip), %rsi       # 0x212a
callq 0x10b0
movq %rax, %rdi
movq 0x2a21(%rip), %rsi      # 0x3fc0
callq 0x10d0
movl 0x3a0(%rsp), %edi
leaq 0x1ec(%rsp), %rsi
movl $0xcc, %edx
xorl %eax, %eax
movl %eax, %ecx
xorl %r8d, %r8d
callq 0x1040
cmpq $-0x1, %rax
jne 0x15fc
movq 0x2a1f(%rip), %rdi      # 0x3ff0
leaq 0xb33(%rip), %rsi       # 0x210b
callq 0x10b0
movq %rax, %rdi
movq 0x29d9(%rip), %rsi      # 0x3fc0
callq 0x10d0
movl $0x1, 0x3b4(%rsp)
jmp 0x17a1
movq 0x29cd(%rip), %rdi      # 0x3fd0
leaq 0xb22(%rip), %rsi       # 0x212c
callq 0x10b0
movq %rax, %rdi
movq 0x29a7(%rip), %rsi      # 0x3fc0
callq 0x10d0
movq 0x29ab(%rip), %rdi      # 0x3fd0
leaq 0xb0d(%rip), %rsi       # 0x2139
callq 0x10b0
movq %rax, %rdi
movq 0x2985(%rip), %rsi      # 0x3fc0
callq 0x10d0
movl $0x0, 0x1d4(%rsp)
cmpl $0x3e8, 0x1d4(%rsp) # imm = 0x3E8
jge 0x177f
xorl %eax, %eax
movl %eax, %esi
leaq 0x1d8(%rsp), %rdi
callq 0x1140
leaq 0x58(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x10e0
movq 0x8(%rsp), %rdi
movq 0x1d8(%rsp), %rsi
callq 0x1170
movq %rax, 0x10(%rsp)
jmp 0x1695
movq 0x10(%rsp), %rdi
leaq 0xa89(%rip), %rsi       # 0x212a
callq 0x10b0
movq %rax, (%rsp)
jmp 0x16ac
movq (%rsp), %rdi
movq 0x1e0(%rsp), %rsi
addq $0xf4240, %rsi          # imm = 0xF4240
callq 0x1170
jmp 0x16c6
leaq 0x28(%rsp), %rdi
leaq 0x58(%rsp), %rsi
callq 0x10c0
jmp 0x16d7
leaq 0x28(%rsp), %rdi
callq 0x1050
movq %rax, 0x20(%rsp)
leaq 0x2bc(%rsp), %rdi
movq 0x20(%rsp), %rsi
callq 0x10a0
movl 0x39c(%rsp), %edi
leaq 0x2b8(%rsp), %rsi
movl $0xcc, %edx
xorl %ecx, %ecx
callq 0x1070
jmp 0x1715
movl $0x3d090, %edi          # imm = 0x3D090
callq 0x10f0
jmp 0x1721
leaq 0x28(%rsp), %rdi
callq 0x1060
leaq 0x58(%rsp), %rdi
callq 0x1030
movl 0x1d4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1d4(%rsp)
jmp 0x164b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x50(%rsp)
movl %eax, 0x4c(%rsp)
jmp 0x1773
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x50(%rsp)
movl %eax, 0x4c(%rsp)
leaq 0x28(%rsp), %rdi
callq 0x1060
leaq 0x58(%rsp), %rdi
callq 0x1030
jmp 0x17b0
movq 0x284a(%rip), %rdi      # 0x3fd0
leaq 0x9b9(%rip), %rsi       # 0x2146
callq 0x10b0
movq %rax, %rdi
movq 0x2824(%rip), %rsi      # 0x3fc0
callq 0x10d0
movl 0x3b4(%rsp), %eax
addq $0x3b8, %rsp            # imm = 0x3B8
retq
movq 0x50(%rsp), %rdi
callq 0x1160