	.file	"leave_critical.c"
	.text
    .globl  leave_critical
	.type	leave_critical, @function
###################################################	
leave_critical:
###################################################	
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%edi
	pushl	%esi
	pushl	%ebx
	subl	$16, %esp
	##########################################
	# your code starts here
	##########################################

	movl 12(%ebp), %eax		#eax = i
	movl (%eax), %eax		#i->next
	cmpl $0x0, %eax			#i->next == NULL
	jne almost_done			#if(i->next == NULL)
	
		#cas	
		movl 12(%ebp), %eax				#eax =  i
		movl 8(%ebp), %ecx				#debug
		movl $0x0, %edx					#edx = null
		lock cmpxchgl %edx, (%ecx)		#cmpxcghl lock and i	
		je done							#if swapped return
			
		loop:							#do {
		movl 12(%ebp),%eax				#eax = i
		cmpl $0x0,(%eax)				#i->next == NULL
		je loop						#}while(i->next == NULL)
		
	almost_done:
		movl 12(%ebp), %eax				#ebx = i
		movl (%eax), %eax				#ebx = i->next
		movl $0,4(%eax)				#i->next->locked = 0
	
	done:
	##########################################
	# your code ends here
	##########################################
	addl	$16, %esp
	popl	%ebx
	popl	%esi
	popl	%edi
	popl	%ebp
	ret
	.size	leave_critical, .-leave_critical
	.ident	"GCC: (SUSE Linux) 4.3.1 20080507 (prerelease) [gcc-4_3-branch revision 135036]"
	.section	.note.GNU-stack,"",@progbits


