Skip to content
This repository has been archived by the owner on Nov 1, 2021. It is now read-only.

Pthreads #67

Merged
merged 31 commits into from
Jun 3, 2015
Merged

Pthreads #67

merged 31 commits into from
Jun 3, 2015

Conversation

juj
Copy link
Collaborator

@juj juj commented Mar 17, 2015

Adds LLVM side support for compiling for the pthreads/atomics support.

This set of commits implements initial pthreads library support for Emscripten code, and allows native code to utilize multithreading with the pthreads API. This backs on experimental research on the JavaScript SharedArrayBuffer and Atomics APIs from https://docs.google.com/document/d/1NDGA_gZJ7M7w1Bh8S0AoDyEqwDdRh4uSoTPSNn77PFk/edit?usp=sharing , and as such is preliminary and unsupported in other browsers except current Firefox Nightly builds. By default pthreads support is disabled, and the feature must be explicitly enabled by specifying the compiler flag -s USE_PTHREADS=1 and the linker flag -lpthread.

@@ -855,15 +927,36 @@ std::string JSWriter::getLoad(const Instruction *I, const Value *P, Type *T, uns
return text;
}

static const std::string AtomicsStore = "Atomics_store(";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a useful optimization here? Is there a specific reason why it is done on this string and not others?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, let me just remove this, it is a leftover from previous form of code. I hope compilers are smart to optimize this on their own anyways.

@juj
Copy link
Collaborator Author

juj commented Mar 24, 2015

Addressed the review comments at juj/emscripten-fastcomp@a5b54c1...0bc3f1a .

std::string getAddressAsString(const Value *Ptr, int shift) {
Type *t = cast<PointerType>(Ptr->getType())->getElementType();
if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Ptr)) {
return utostr(getGlobalAddress(GV->getName().str()) >> shift);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getGlobalAddress returns a number. that number does not include a relocation offset, which we need in shared modules. relocateGlobal will do a relocation for you (it operates on a string, so need to take into account the shift on the extra part here).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, fixed. Although note that threads and shared libraries is not supported at present, that is left for later.

juj added 20 commits June 1, 2015 15:07
…ontrol whether targeting multithreading with Atomics and SAB or not.
… GCC intrinsics to Emscripten library function calls. Mark 64-bit AtomicCmpXchg instructions unsupported at the moment.
…und, do it as u32 version with a CAS loop. TODO: revert this commit once https://bugzilla.mozilla.org/show_bug.cgi?id=1141986 lands.
@juj
Copy link
Collaborator Author

juj commented Jun 1, 2015

Addressed the review comments and rebased on top of the latest. This should hopefully look simpler now?

@@ -549,6 +554,154 @@ DEF_CALL_HANDLER(emscripten_asm_const_double, {
return getAssign(CI) + getCast(handleAsmConst(CI), Type::getDoubleTy(CI->getContext()));
})

std::string getAddressAsString(const Value *Ptr, int shift) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's call this getShiftedPtr, as it works on pointers, and it doesn't return just a string, but specifically it returns a shifted result (so it isn't the real pointer/address anymore).

Also, please move this to right before getPtrUse in the main JSBackend.cpp file. Then the distinction between the two methods is clear.

And once at that location, it looks like we can remove getHeapAccess, and instead implement getPtrUse using the new getShiftedPtr (the only extra thing needed is HEAP?[ on the left and ] on the right, can do that in getPtrUse, or alternatively leave getHeapAccess but without the shifting inside it, so all it does is add the HEAP?[ and ]; I am ok with either).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see there is getHeapName, so can use that for the HEAP? part, leaving just [ and ].

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or actually instead of everything I said, this method could be implemented using the getHeapNameAndIndex family of methods.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyhow, sorry to ramble here, but in summary

  1. I think getShiftedPtr is a better name
  2. I'd prefer this to be implemented using other methods, without a special check on GlobalVariable, and without the need to relocateGlobal, as the other methods already do both.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, updated the pull request to rename this to getShiftedPtr and to reuse the existing code as much as possible.

@kripken
Copy link
Member

kripken commented Jun 1, 2015

Looks nice, thanks.

One last thing, just to be sure, please test compilation time before and after this pull. I'm not too worried, but still this changes a lot of the string handling code in emitting pointer uses in the backend. A quick test on a large codebase of js backend time, with and without this pull, should be enough to check.

If that is ok, then lgtm.

@juj
Copy link
Collaborator Author

juj commented Jun 2, 2015

I rebuilt Unity3D three times with trunk and both pthreads PRs applied, with the following results:

incoming:
emscript: llvm backend took 11.1803879738 seconds
emscript: llvm backend took 10.9915230274 seconds
emscript: llvm backend took 10.9425158501 seconds

pthreads:
emscript: llvm backend took 11.1047959328 seconds
emscript: llvm backend took 11.1267051697 seconds
emscript: llvm backend took 11.0028831959 seconds

so the differences do look quite negligible. I'll go ahead and merge these in, if everything is set?

@kripken
Copy link
Member

kripken commented Jun 3, 2015

Sure!

juj added a commit that referenced this pull request Jun 3, 2015
@juj juj merged commit 4d008e1 into emscripten-core:incoming Jun 3, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants