diff --git a/sortix/Makefile b/sortix/Makefile
index 331629d7..8e62966d 100644
--- a/sortix/Makefile
+++ b/sortix/Makefile
@@ -87,7 +87,6 @@ bga.o \
calltrace.o \
com.o \
$(CPU)/calltrace.o \
-$(CPU)/interlock.o \
$(CPU)/kthread.o \
crc32.o \
descriptors.o \
diff --git a/sortix/include/sortix/kernel/interlock.h b/sortix/include/sortix/kernel/interlock.h
index a4496231..e4cdf27a 100644
--- a/sortix/include/sortix/kernel/interlock.h
+++ b/sortix/include/sortix/kernel/interlock.h
@@ -1,6 +1,6 @@
/*******************************************************************************
- Copyright(C) Jonas 'Sortie' Termansen 2012.
+ Copyright(C) Jonas 'Sortie' Termansen 2012, 2013.
This file is part of Sortix.
@@ -34,7 +34,7 @@ typedef struct
unsigned long n; // new value
} ilret_t;
-// These atomicly modifies a value and return the previous value.
+// These atomically modifies a value and return the previous value.
ilret_t InterlockedModify(unsigned long* ptr,
ilockfunc f,
unsigned long user = 0);
diff --git a/sortix/interlock.cpp b/sortix/interlock.cpp
index e3a82242..f199681d 100644
--- a/sortix/interlock.cpp
+++ b/sortix/interlock.cpp
@@ -1,6 +1,6 @@
/*******************************************************************************
- Copyright(C) Jonas 'Sortie' Termansen 2012.
+ Copyright(C) Jonas 'Sortie' Termansen 2012, 2013.
This file is part of Sortix.
@@ -29,15 +29,20 @@ namespace Sortix {
// TODO: This is likely not the most optimal way to perform these operations.
-extern "C" ilret_t asm_interlocked_modify(unsigned long* val,
- ilockfunc f,
- unsigned long user);
-
ilret_t InterlockedModify(unsigned long* ptr,
ilockfunc f,
unsigned long user)
{
- return asm_interlocked_modify(ptr, f, user);
+ unsigned long old_value, new_value;
+ do
+ {
+ old_value = *((volatile unsigned long*) ptr); /* TODO: Need volatile? */
+ new_value = f(old_value, user);
+ } while ( !__sync_bool_compare_and_swap(ptr, old_value, new_value) );
+ ilret_t ret;
+ ret.o = old_value;
+ ret.n = new_value;
+ return ret;
}
static unsigned long AddFunction(unsigned long val, unsigned long arg)
diff --git a/sortix/x64/interlock.s b/sortix/x64/interlock.s
deleted file mode 100644
index d7430040..00000000
--- a/sortix/x64/interlock.s
+++ /dev/null
@@ -1,56 +0,0 @@
-/*******************************************************************************
-
- Copyright(C) Jonas 'Sortie' Termansen 2012.
-
- This file is part of Sortix.
-
- Sortix is free software: you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation, either version 3 of the License, or (at your option) any later
- version.
-
- Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- details.
-
- You should have received a copy of the GNU General Public License along with
- Sortix. If not, see .
-
- x64/interlock.s
- Functions that perform non-atomic operations in an atomic manner.
-
-*******************************************************************************/
-
-.section .text
-
-# Atomicly runs a function on a value and returns the unmodified value.
-# ilret_t
-# asm_interlocked_modify(unsigned long* val,
-# unsigned long (*func)(unsigned long, unsigned long),
-# unsigned long user);
-.global asm_interlocked_modify
-.type asm_interlocked_modify, @function
-asm_interlocked_modify:
- pushq %rbp
- movq %rsp, %rbp
-asm_interlocked_modify_retry:
- # Save our parameters in case we need to retry.
- pushq %rdi
- pushq %rsi
- pushq %rdx
- # Read the current value and calculate the replacement.
- movq (%rdi), %rdi
- movq %rdx, %rsi
- callq *%rsi
- movq %rax, %rdx
- popq %rax
- popq %rdi
- popq %rsi
- # Atomicly assign the replacement if the value is unchanged.
- cmpxchgq %rdx, (%rdi)
- # Retry if the value was modified by someone else.
- jnz asm_interlocked_modify_retry
- # Return the old value in %rax, new one in %rdx.
- leaveq
- retq
diff --git a/sortix/x86/interlock.s b/sortix/x86/interlock.s
deleted file mode 100644
index 12f990b5..00000000
--- a/sortix/x86/interlock.s
+++ /dev/null
@@ -1,61 +0,0 @@
-/*******************************************************************************
-
- Copyright(C) Jonas 'Sortie' Termansen 2012.
-
- This file is part of Sortix.
-
- Sortix is free software: you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation, either version 3 of the License, or (at your option) any later
- version.
-
- Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- details.
-
- You should have received a copy of the GNU General Public License along with
- Sortix. If not, see .
-
- x86/interlock.s
- Functions that perform non-atomic operations in an atomic manner.
-
-*******************************************************************************/
-
-.section .text
-
-# Atomicly runs a function on a value and returns the unmodified value.
-# ilret_t
-# asm_interlocked_modify(unsigned long* val,
-# unsigned long (*func)(unsigned long, unsigned long),
-# unsigned long user);
-.global asm_interlocked_modify
-.type asm_interlocked_modify, @function
-asm_interlocked_modify:
- pushl %ebp
- movl %esp, %ebp
- pushl %ebx
-asm_interlocked_modify_retry:
- # Read the current value and calculate the replacement.
- movl 20(%ebp), %ecx # user
- movl 16(%ebp), %edx # func
- movl 12(%ebp), %ebx # val
- movl (%ebx), %ebx # *val
- pushl %ecx
- pushl %ebx
- call *%edx
- # Atomicly assign the replacement if the value is unchanged.
- movl %eax, %edx # New value in %edx
- movl %ebx, %eax # Old value in %eax
- movl 8(%ebp), %ebx # val
- cmpxchgl %edx, (%ebx)
- # Retry if the value was modified by someone else.
- jnz asm_interlocked_modify_retry
- # According to the calling convention, the first parameter is secretly a
- # pointer to where we store the result, the old value first, then the new.
- movl 8(%ebp), %ebx
- movl %eax, 0(%ebx)
- movl %edx, 4(%ebx)
- popl %ebx
- leavel
- retl $0x4