Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix slp_switch on SPARC for multi-threaded environments #31

Merged
merged 1 commit into from
Sep 2, 2013
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 25 additions & 7 deletions platform/switch_sparc_sun_gcc.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
* this is the internal transfer function.
*
* HISTORY
* 30-Aug-13 Floris Bruynooghe <[email protected]>
Clean the register windows again before returning.
This does not clobber the PIC register as it leaves
the current window intact and is required for multi-
threaded code to work correctly.
* 08-Mar-11 Floris Bruynooghe <[email protected]>
* No need to set return value register explicitly
* before the stack and framepointer are adjusted
Expand All @@ -28,7 +33,8 @@


#define STACK_MAGIC 0
#define ST_FLUSH_WINDOWS 3
#define ST_FLUSH_WINDOWS 0x03
#define ST_CLEAN_WINDOWS 0x04

static int
slp_switch(void)
Expand All @@ -37,7 +43,17 @@ slp_switch(void)

/* Flush SPARC register windows onto the stack, so they can be used to
* restore the registers after the stack has been switched out and
* restored. Then put the stack pointer into stackref. */
* restored. This also ensures the current window (pointed at by
* the CWP register) is the only window left in the registers
* (CANSAVE=0, CANRESTORE=0), that means the registers of our
* caller are no longer there and when we return they will always
* be loaded from the stack by a window underflow/fill trap.
*
* On SPARC v9 and above it might be more efficient to use the
* FLUSHW instruction instead of TA ST_FLUSH_WINDOWS. But that
* requires the correct -mcpu flag to gcc.
*
* Then put the stack pointer into stackref. */
__asm__ volatile (
"ta %1\n\t"
"mov %%sp, %0"
Expand All @@ -57,11 +73,13 @@ slp_switch(void)
/* Copy new stack from it's save store on the heap */
SLP_RESTORE_STATE();

/* No need to restore any registers from the stack nor clear them: the
* frame pointer has just been set and the return value register is
* also being set by the return statement below. After returning a
* restore instruction is given and the frame below us will load all
* it's registers using a fill_trap if required. */
/* No need to set the return value register, the return
* statement below does this just fine. After returning a restore
* instruction is given and a fill-trap will load all the registers
* from the stack if needed. However in a multi-threaded environment
* we can't guarantee the other register windows are fine to use by
* their threads anymore, so tell the CPU to clean them. */
__asm__ volatile ("ta %0" : : "i" (ST_CLEAN_WINDOWS));

return 0;
}
Expand Down