Aquire Singleton classe Instance Multithread

Para obter a instância da classe com o padrão Singleton, quero usar a seguinte função:

Este é um esboço

interface

uses SyncObjs;

type
  TMCriticalSection = class(TCriticalSection)
  private
    Dummy : array [0..95] of Byte;
  end;

var
  InstanceNumber : Integer;
  AObject: TObject;
  CriticalSection: TMCriticalSection;

function getInstance: TObject;

implementation

uses Windows;

function getInstance: TObject;
begin
   //I Want somehow use InterlockedCompareExchange instead of CriticalSession, for example

   if InterlockedCompareExchange(InstanceNumber, 1, 0) > 0 then
   begin
     Result := AObject;
   end
   else
   begin
      CriticalSection.Enter;
      try
        AObject := TObject.Create;
      finally
        CriticalSection.Leave;
      end;
      InterlockedIncrement(InstanceNumber);
      Result := AObject
   end;
end;

initialization
  CriticalSection := TMCriticalSection.Create;
  InstanceNumber := 0;

finalization;
  CriticalSection.Free;

end.

Três perguntas:

1- Este design é seguro para roscas? Especialmente com o InterlockedExchange Part.
2- Como usar o InterlockedCompareExchange? É possível fazer o que estou tentando?
3- Este design é melhor do que envolver todo o código dentro do escopo da seção crítica?

Observação: Meu objeto é thread-safe, apenas a construção que eu preciso para serializar!
Este não é o código intire, apenas a parte importante, quero dizer, a função getInstance.

Editar

I PRECISAR para usar algum tipo de objeto singleton.
Existe alguma maneira de usar InterlockedCompareExchange para comparar se o valor de InstanceNumber for zero?
E
1 - Crie o objeto somente quando for 0, caso contrário, retorne a instância.
2 - Quando o valor é 0: insira a seção crítica. Crie o objeto. Deixe a seção crítica.
3 - Seria melhor fazer isso, em vez de envolver todo o código dentro do escopo da seção crítica?

questionAnswers(2)

yourAnswerToTheQuestion