GitLab will continue to be upgraded from 11.4.5-ce.0 on November 25th 2019 at 4.00pm (AEDT) to 5.00pm (AEDT) due to Critical Security Patch Availability. During the update, GitLab and Mattermost services will not be available.

Commit 51d3bbbf authored by Kunshan Wang's avatar Kunshan Wang

Implementing futex...

parent 7e5164ee
......@@ -28,6 +28,8 @@ object CommInsts extends SimpleNamespace[CommInst] {
commInst(0x21a, "@uvm.tr64.to_tag")
commInst(0x220, "@uvm.futex.wait")
commInst(0x221, "@uvm.futex.wake")
commInst(0x221, "@uvm.futex.wait_timeout")
commInst(0x222, "@uvm.futex.wake")
commInst(0x223, "@uvm.futex.cmp_requeue")
}
\ No newline at end of file
......@@ -23,6 +23,7 @@ object InternalTypes {
val I1 = TypeInt(1) := internal("i1")
val I6 = TypeInt(6) := internal("i6")
val I32 = TypeInt(32) := internal("i32")
val I52 = TypeInt(52) := internal("i52")
val I64 = TypeInt(52) := internal("i64")
val DOUBLE = TypeDouble() := internal("double")
......@@ -125,8 +126,10 @@ object TypeInferer {
case "@uvm.tr64.to_int" => I52
case "@uvm.tr64.to_ref" => REF_VOID
case "@uvm.tr64.to_tag" => I6
case "@uvm.futex.wait" => I64
case "@uvm.futex.wake" => I64
case "@uvm.futex.wait" => I32
case "@uvm.futex.wait_timeout" => I32
case "@uvm.futex.wake" => I32
case "@uvm.futex.cmp_requeue" => I32
}
}
}
\ No newline at end of file
package uvm.refimpl.itpr
import uvm.refimpl.mem.TypeSizes.Word
import scala.collection.mutable.{ HashSet, HashMap, MultiMap, ListBuffer, Set, TreeSet }
import scala.math.Ordering
/**
* This class manages Futexes.
*/
class FutexManager {
case class WaitRecord(val objRef: Word, val offset: Word, val loc: Word, val thread: InterpreterThread, val autoWakeup: Option[Long])
type WaitingQueueType = ListBuffer[WaitRecord]
type WaitingQueuesType = HashMap[Word, WaitingQueueType]
/** One waiting queue for each memory location (address). */
private val waitingQueues = new WaitingQueuesType()
/** Maps each object address to all its internal locations. Non-heap locations has objRef==0. */
private val objIndex = new HashMap[Word, Set[Word]] with MultiMap[Word, Word]
/** Waiting threads with timeout */
private val timeoutSet = new TreeSet[WaitRecord]()(Ordering.by(_.autoWakeup.get))
def futexWaitNoCheck(objRef: Word, offset: Word, thread: InterpreterThread, maybeTimeout: Option[Long] = None): Unit = {
thread.isFutexWaiting = true
val loc = objRef + offset
val autoWakeup = maybeTimeout.map { timeout =>
val now = System.currentTimeMillis()
timeout + now * 1000000L
}
val wr = WaitRecord(objRef, offset, loc, thread, autoWakeup)
val q = waitingQueues.getOrElseUpdate(loc, new WaitingQueueType)
q.append(wr)
objIndex.addBinding(objRef, loc)
if (autoWakeup.isDefined) {
timeoutSet.add(wr)
}
}
def futexWake(objRef: Word, offset: Word, nThread: Int): Unit = {
val loc = objRef + offset
waitingQueues.get(loc).foreach { q =>
val wrs = q.take(nThread)
for (wr <- wrs) {
wr.thread.isFutexWaiting = false
timeoutSet.remove(wr)
}
if (wrs.size <= q.size) {
waitingQueues.remove(loc)
objIndex.removeBinding(objRef, loc)
} else {
q.remove(0, wrs.size)
}
}
}
def futexWakeTimeout(): Unit = {
val now = System.currentTimeMillis() * 1000000L
while (!timeoutSet.isEmpty) {
val first = timeoutSet.firstKey
if (first.autoWakeup.get <= now) {
first.thread.isFutexWaiting = false
timeoutSet.remove(first)
}
}
}
def futexRequeue(objRefSrc: Word, offsetSrc: Word, objRefDst: Word, offsetDst: Word, nThread: Int): Unit = {
val locSrc = objRefSrc + offsetSrc
val locDst = objRefDst + offsetDst
waitingQueues.get(locSrc).foreach { q =>
waitingQueues.remove(locSrc)
objIndex.removeBinding(objRefSrc, locSrc)
val wakes = q.take(nThread)
for (wr <- wakes) {
wr.thread.isFutexWaiting = false
timeoutSet.remove(wr)
}
val moves = q.drop(nThread)
if (!moves.isEmpty) {
objIndex.addBinding(objRefDst, locDst)
waitingQueues.get(locDst) match {
case None => {
waitingQueues(locDst) = moves
}
case Some(qDst) => {
qDst.appendAll(moves)
}
}
}
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment