public void run()
		{
			//---------------------------------------
			//Mutex wait ensure atomicity of phase 1
			//---------------------------------------
			mutex.P();
			System.out.println("\n\n*******************************************************");
			System.out.println("ReleaseBlock thread [TID=" + this.iTID + "] starts executing.");
			
			
			phase1();

			try
			{
				if(soStack.isEmpty() == false)
					this.cBlock = (char)(soStack.pick() + 1);


				System.out.println
				(
					"ReleaseBlock thread [TID=" + this.iTID + "] returns Ms block " + this.cBlock +
					" to position " + (soStack.getiTop() + 1) + "."
				);

				soStack.push(this.cBlock);

				System.out.println
				(
					"Rel[TID=" + this.iTID + "]: Current value of top = " +
					soStack.getiTop() + "."
				);

				System.out.println
				(
					"Rel[TID=" + this.iTID + "]: Current value of stack top = " +
					soStack.pick() + "."
				);
			}
			catch(Exception e)
			{
				reportException(e);
				System.exit(1);
			}
			//----------------------------------------
			//Release mutex once Phase 1 is completed
			//----------------------------------------
			mutex.V();
			
			
			//------------------------------------------------
			//Using semaphores we ensure that Phase 2 doesn't
			//start before all Phase 1 are complete
			//------------------------------------------------	
			s1.V();
			s2.P();
			s2.V();
			
			
			//---------------------------------------------
			//Continually checks whether or not if current 
			//thread is allowed to go
			//---------------------------------------------
			do
			{
				mutex.P();
				if(this.turnTestAndSet())
				{
					phase2();
					break;
				}
				mutex.V();
			}while(!this.turnTestAndSet());
			
			mutex.V();
			
		


			System.out.println("ReleaseBlock thread [TID=" + this.iTID + "] terminates.");
			System.out.println("*******************************************************\n\n");
			
			
			
		}