Before I convert this code into AT&T syntax for GAS to assemble, and to
MASM
I was wondering if there are any possible optimizations I can perform on
the
following code, I will show the C header first:
cpusync_i686.h
________________________________________________________________
#if ! defined(CPUSYNC_i686_H)
# define CPUSYNC_i686_H
# undef EXTERN
# if defined(__cplusplus)
# define EXTERN extern "C"
# else
# define EXTERN extern
# endif
/*************************************************************/
typedef int atomicword_i686;
typedef atomicword_i686 spinlock_i686;
typedef struct nbnode_i686_s nbnode_i686;
typedef struct nblifo_i686_s nblifo_i686;
struct nbnode_i686_s {
nbnode_i686* next;
};
struct nblifo_i686_s {
nbnode_i686* head;
atomicword_i686 aba;
};
#define SPINLOCK_I686_STATICINIT() { 0 }
#define NBLIFO_I686_STATICINIT() { 0 }
typedef char cpusync_i686_static_assert[
((sizeof(atomicword_i686) == 4) &&
(sizeof(spinlock_i686) == 4) &&
(sizeof(nbnode_i686) == 4) &&
(sizeof(nblifo_i686) == 8)
) ? 1 : -1
];
EXTERN void
spinlock_i686_acquire(
atomicword_i686* const
);
EXTERN void
spinlock_i686_release(
atomicword_i686* const
);
EXTERN void
nblifo_i686_push(
nblifo_i686* const,
nbnode_i686* const
);
EXTERN nbnode_i686*
nblifo_i686_flush(
nblifo_i686* const
);
EXTERN nbnode_i686*
nblifo_i686_pop(
nblifo_i686* const
);
/*************************************************************/
#endif
________________________________________________________________
Here is the temporary implementation which compiles with VC++:
cpusync_i686.c
________________________________________________________________
__declspec(naked) void
spinlock_i686_acquire(
atomicword_i686* const _this
) {
_asm {
MOV ECX, [ESP + 4]
MOV EAX, 1
spinlock_i686_acquire_retry:
XCHG [ECX], EAX
TEST EAX, EAX
JNZ spinlock_i686_acquire_failed
RET
spinlock_i686_acquire_failed:
PAUSE
JMP spinlock_i686_acquire_retry
}
}
__declspec(naked) void
spinlock_i686_release(
atomicword_i686* const _this
) {
_asm {
MOV ECX, [ESP + 4]
MOV EAX, 0
MOV [ECX], EAX
RET
}
}
__declspec(naked) void
nblifo_i686_push(
nblifo_i686* const _this,
nbnode_i686* const node
) {
_asm {
MOV EDX, [ESP + 4]
MOV EAX, [EDX]
MOV ECX, [ESP + 8]
nblifo_i686_push_retry:
MOV [ECX], EAX
LOCK CMPXCHG [EDX], ECX
JNE nblifo_i686_push_retry
RET
}
}
__declspec(naked) nbnode_i686*
nblifo_i686_pop(
nblifo_i686* const _this
) {
_asm {
PUSH ESI
PUSH EBX
MOV ESI, [ESP + 12]
MOV EDX, [ESI + 4]
MOV EAX, [ESI]
nblifo_i686_pop_retry:
TEST EAX, EAX
JZ nblifo_i686_pop_fail
MOV EBX, [EAX]
LEA ECX, [EDX + 1]
LOCK CMPXCHG8B QWORD PTR [ESI]
JNE nblifo_i686_pop_retry
nblifo_i686_pop_fail:
POP EBX
POP ESI
RET
}
}
__declspec(naked) nbnode_i686*
nblifo_i686_flush(
nblifo_i686* const _this
) {
_asm {
MOV ECX, [ESP + 4]
MOV EAX, 0
XCHG [ECX], EAX
RET
}
}
________________________________________________________________
AFAICT, everything seems to look okay. However, I am not an expert x86
programmer! Any comments/suggestions would be highly appreciated.
Thanks.
--
Chris M. Thomasson
http://appcore.home.comcast.net


|