Skip to content

File instr_pool.h

File List > projects > simtix > src > simtix > sm > instr_pool.h

Go to the documentation of this file

#pragma once

#include <cassert>
#include <vector>

#include "sm/instr.h"

namespace simtix {

class InstrPoolInterface {
 public:
  virtual Instr *Allocate(Warp *, uint32_t, uint64_t) = 0;
  virtual void Recycle(Instr *) = 0;
};

template <class InstrType>
class InstrPool : public InstrPoolInterface {
 public:
  InstrPool(const InstrPool &) = delete;
  InstrPool &operator=(const InstrPool &) = delete;

  Instr *Allocate(Warp *warp, uint32_t iword, uint64_t wpc) override {
    assert(warp);
    Instr *t = nullptr;

    // Reuse the object in the pool when not empty, otherwise allocate a new one
    if (pool_.empty()) {
      t = new InstrType(warp, iword, wpc);
    } else {
      t = pool_.back();
      t->Reinitialize(warp, iword, wpc);
      pool_.pop_back();
    }

    return t;
  }

  void Recycle(Instr *instr) override {
    assert(instr);
    instr->Reset();
    pool_.emplace_back(instr);  // Put the object back to the pool
  }

  inline size_t size() const { return pool_.size(); }

  static InstrPool &GetInstance() {
    static InstrPool pool(INITIAL_INSTR_POOL_SIZE);
    return pool;
  }

 private:
  explicit InstrPool(size_t size) {
    for (size_t i = 0; i < size; ++i) {
      pool_.emplace_back(new InstrType(nullptr, 0, 0));
    }
  }

  ~InstrPool() {
    for (size_t i = 0; i < pool_.size(); ++i) {
      delete pool_[i];
    }
    pool_.clear();
  }

  std::vector<Instr *> pool_;
};

}  // namespace simtix