syscall_emul.hh (13650:93efc0143eb7) syscall_emul.hh (13651:b33db942f760)
1/*
2 * Copyright (c) 2012-2013, 2015 ARM Limited
3 * Copyright (c) 2015 Advanced Micro Devices, Inc.
4 * All rights reserved
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating

--- 441 unchanged lines hidden (view full) ---

450 int mem_val = *(int*)buf.bufferPtr();
451 /*
452 * For CMP_REQUEUE, the whole operation is only started only if
453 * val3 is still the value of the futex pointed to by uaddr.
454 */
455 if (OS::TGT_FUTEX_CMP_REQUEUE && val3 != mem_val)
456 return -OS::TGT_EWOULDBLOCK;
457 return futex_map.requeue(uaddr, process->tgid(), val, timeout, uaddr2);
1/*
2 * Copyright (c) 2012-2013, 2015 ARM Limited
3 * Copyright (c) 2015 Advanced Micro Devices, Inc.
4 * All rights reserved
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating

--- 441 unchanged lines hidden (view full) ---

450 int mem_val = *(int*)buf.bufferPtr();
451 /*
452 * For CMP_REQUEUE, the whole operation is only started only if
453 * val3 is still the value of the futex pointed to by uaddr.
454 */
455 if (OS::TGT_FUTEX_CMP_REQUEUE && val3 != mem_val)
456 return -OS::TGT_EWOULDBLOCK;
457 return futex_map.requeue(uaddr, process->tgid(), val, timeout, uaddr2);
458 } else if (OS::TGT_FUTEX_WAKE_OP == op) {
459 /*
460 * The FUTEX_WAKE_OP operation is equivalent to executing the
461 * following code atomically and totally ordered with respect to
462 * other futex operations on any of the two supplied futex words:
463 *
464 * int oldval = *(int *) addr2;
465 * *(int *) addr2 = oldval op oparg;
466 * futex(addr1, FUTEX_WAKE, val, 0, 0, 0);
467 * if (oldval cmp cmparg)
468 * futex(addr2, FUTEX_WAKE, val2, 0, 0, 0);
469 *
470 * (op, oparg, cmp, cmparg are encoded in val3)
471 *
472 * +---+---+-----------+-----------+
473 * |op |cmp| oparg | cmparg |
474 * +---+---+-----------+-----------+
475 * 4 4 12 12 <== # of bits
476 *
477 * reference: http://man7.org/linux/man-pages/man2/futex.2.html
478 *
479 */
480 // get value from simulated-space
481 BufferArg buf(uaddr2, sizeof(int));
482 buf.copyIn(tc->getMemProxy());
483 int oldval = *(int*)buf.bufferPtr();
484 int newval = oldval;
485 // extract op, oparg, cmp, cmparg from val3
486 int wake_cmparg = val3 & 0xfff;
487 int wake_oparg = (val3 & 0xfff000) >> 12;
488 int wake_cmp = (val3 & 0xf000000) >> 24;
489 int wake_op = (val3 & 0xf0000000) >> 28;
490 if ((wake_op & OS::TGT_FUTEX_OP_ARG_SHIFT) >> 3 == 1)
491 wake_oparg = (1 << wake_oparg);
492 wake_op &= ~OS::TGT_FUTEX_OP_ARG_SHIFT;
493 // perform operation on the value of the second futex
494 if (wake_op == OS::TGT_FUTEX_OP_SET)
495 newval = wake_oparg;
496 else if (wake_op == OS::TGT_FUTEX_OP_ADD)
497 newval += wake_oparg;
498 else if (wake_op == OS::TGT_FUTEX_OP_OR)
499 newval |= wake_oparg;
500 else if (wake_op == OS::TGT_FUTEX_OP_ANDN)
501 newval &= ~wake_oparg;
502 else if (wake_op == OS::TGT_FUTEX_OP_XOR)
503 newval ^= wake_oparg;
504 // copy updated value back to simulated-space
505 *(int*)buf.bufferPtr() = newval;
506 buf.copyOut(tc->getMemProxy());
507 // perform the first wake-up
508 int woken1 = futex_map.wakeup(uaddr, process->tgid(), val);
509 int woken2 = 0;
510 // calculate the condition of the second wake-up
511 bool is_wake2 = false;
512 if (wake_cmp == OS::TGT_FUTEX_OP_CMP_EQ)
513 is_wake2 = oldval == wake_cmparg;
514 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_NE)
515 is_wake2 = oldval != wake_cmparg;
516 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_LT)
517 is_wake2 = oldval < wake_cmparg;
518 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_LE)
519 is_wake2 = oldval <= wake_cmparg;
520 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_GT)
521 is_wake2 = oldval > wake_cmparg;
522 else if (wake_cmp == OS::TGT_FUTEX_OP_CMP_GE)
523 is_wake2 = oldval >= wake_cmparg;
524 // perform the second wake-up
525 if (is_wake2)
526 woken2 = futex_map.wakeup(uaddr2, process->tgid(), timeout);
527
528 return woken1 + woken2;
458 }
459 warn("futex: op %d not implemented; ignoring.", op);
460 return -ENOSYS;
461}
462
463
464/// Pseudo Funcs - These functions use a different return convension,
465/// returning a second value in a register other than the normal return register

--- 2241 unchanged lines hidden ---
529 }
530 warn("futex: op %d not implemented; ignoring.", op);
531 return -ENOSYS;
532}
533
534
535/// Pseudo Funcs - These functions use a different return convension,
536/// returning a second value in a register other than the normal return register

--- 2241 unchanged lines hidden ---