Class: Origen::Generator::PatternSequencer

Inherits:
Object
  • Object
show all
Defined in:
lib/origen/generator/pattern_sequencer.rb

Overview

Provides APIs to enable applications to support concurrency

Class Method Summary collapse

Class Method Details

.active?Boolean Also known as: open?, runnng?

Returns true if a pattern sequence is currently open/active

Returns:

  • (Boolean)


64
65
66
# File 'lib/origen/generator/pattern_sequencer.rb', line 64

def active?
  !!@active
end

.add_thread(str) ⇒ Object

Prepends the given string with “[<current thread ID>] ” unless it already contains it



76
77
78
79
80
81
82
# File 'lib/origen/generator/pattern_sequencer.rb', line 76

def add_thread(str)
  if active? && thread
    id = "[#{thread.id}] "
    str.prepend(id) unless str =~ /#{id}/
  end
  str
end

.reserve(id) ⇒ Object

Once a lock is acquired on a serialize block with the given ID, it won't be released to other parallel threads until the end of this block



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/origen/generator/pattern_sequencer.rb', line 41

def reserve(id)
  if active?
    if thread.reservations[id]
      thread.reservations[id][:count] += 1
    else
      thread.reservations[id] = { count: 1, semaphore: nil }
    end
    yield
    if thread.reservations[id][:count] == 1
      # May not be set if the application reserved the resource but never hit it
      if s = thread.reservations[id][:semaphore]
        s.release
      end
      thread.reservations[id] = nil
    else
      thread.reservations[id][:count] -= 1
    end
  else
    yield
  end
end

.serialize(id = nil) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/origen/generator/pattern_sequencer.rb', line 7

def serialize(id = nil)
  if active?
    s = nil
    id ||= caller[0]
    @semaphores ||= {}
    @semaphores[id] ||= Concurrent::Semaphore.new(1)
    s = @semaphores[id]
    completed = false
    blocked = false
    until completed
      # If already acquired or available
      if (thread.reservations[id] && thread.reservations[id][:semaphore]) || s.try_acquire
        thread.record_active if blocked
        yield
        completed = true
      else
        thread.waiting_for_serialize(id, blocked)
        blocked = true
      end
    end
    # If the thread has reserved access to this serialized resource then don't release it now, but
    # store a reference to the semaphore and it will be released at the end of the reserve block
    if thread.reservations[id]
      thread.reservations[id][:semaphore] = s
    else
      s.release
    end
  else
    yield
  end
end

.sync_up(*ids) ⇒ Object



93
94
95
96
97
# File 'lib/origen/generator/pattern_sequencer.rb', line 93

def sync_up(*ids)
  if @current_sequence
    @current_sequence.send(:sync_up, caller[0], *ids)
  end
end

.threadObject

Returns the PatternThread object for the current thread



71
72
73
# File 'lib/origen/generator/pattern_sequencer.rb', line 71

def thread
  @thread.value
end

.wait_for_threads_to_complete(*ids) ⇒ Object Also known as: wait_for_thread, wait_for_threads, wait_for_thread_to_complete

Wait for the given threads to complete. If no IDs given it will wait for all currently running threads (except for the one who called this) to complete.



86
87
88
# File 'lib/origen/generator/pattern_sequencer.rb', line 86

def wait_for_threads_to_complete(*ids)
  @current_sequence.wait_for_threads_to_complete(*ids)
end