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

Make Stylist no longer an unsafe pointer once we have fast RWArcs #2604

Closed
pcwalton opened this issue Jun 6, 2014 · 23 comments
Closed

Make Stylist no longer an unsafe pointer once we have fast RWArcs #2604

pcwalton opened this issue Jun 6, 2014 · 23 comments
Assignees

Comments

@pcwalton
Copy link
Contributor

@pcwalton pcwalton commented Jun 6, 2014

Currently RWArcs use Sems and that is very slow. Once that is no longer the case, put Stylist in an RWArc.

@SimonSapin
Copy link
Member

@SimonSapin SimonSapin commented Aug 12, 2014

RWArc<T> is gone, replaced by Arc<RWLock<T>>. Does RWLock still have the same perf problems?

@pcwalton
Copy link
Contributor Author

@pcwalton pcwalton commented Mar 2, 2015

@SimonSapin I believe RWLock is fast now, looking at Rust. We'll need to benchmark to make sure.

@kmcallister kmcallister added the E-easy label May 12, 2015
@mt2d2
Copy link
Contributor

@mt2d2 mt2d2 commented Jul 3, 2015

Took a look at this with help from @Ms2ger on IRC—an implementation moving the Stylist from LayoutTaskData to LayoutTask as an Arc<RwLock<Stylist>> panics with a deadlock. Similar deadlock seen when simply using a Mutex (albeit no panic). No luck, open to suggestions!

@jdm jdm added E-less easy and removed E-easy labels Jul 3, 2015
@Ms2ger
Copy link
Contributor

@Ms2ger Ms2ger commented Jul 6, 2015

@pcwalton
Copy link
Contributor Author

@pcwalton pcwalton commented Jul 6, 2015

Probably needs finer-grained locking inside the Stylist then?

eefriedman added a commit to eefriedman/servo that referenced this issue Sep 3, 2015
Not sure if this is the best way to structure the code; there are a lot
of mutexes involved.

Fixes servo#2604. Pretty sure the issue with the other version mentioned
there was just that it held on to the lock too long.
eefriedman added a commit to eefriedman/servo that referenced this issue Sep 3, 2015
Not sure if this is the best way to structure the code; there are a lot
of mutexes involved.

Fixes servo#2604. Pretty sure the issue with the other version mentioned
there was just that it held on to the lock too long.
eefriedman added a commit to eefriedman/servo that referenced this issue Sep 4, 2015
Not sure if this is the best way to structure the code; there are a lot
of mutexes involved.

Fixes servo#2604. Pretty sure the issue with the other version mentioned
there was just that it held on to the lock too long.
eefriedman added a commit to eefriedman/servo that referenced this issue Sep 10, 2015
Making the Stylist usage threadsafe without unsafe code or extra locking
required some changes to WorkQueue; the changes are mostly straightforward.

Fixes servo#2604. Pretty sure the issue with the other version mentioned
there was just that it held on to the lock too long.
eefriedman added a commit to eefriedman/servo that referenced this issue Sep 10, 2015
Making the Stylist usage threadsafe without unsafe code or extra locking
required some changes to WorkQueue; the changes are mostly straightforward.

Fixes servo#2604. Pretty sure the issue with the other version mentioned
there was just that it held on to the lock too long.
eefriedman added a commit to eefriedman/servo that referenced this issue Sep 10, 2015
Making the Stylist usage threadsafe without unsafe code or extra locking
required some changes to WorkQueue; the changes are mostly straightforward.

Fixes servo#2604. Pretty sure the issue with the other version mentioned
there was just that it held on to the lock too long.
eefriedman added a commit to eefriedman/servo that referenced this issue Sep 15, 2015
Making the Stylist usage threadsafe without unsafe code or extra locking
required some changes to WorkQueue; the changes are mostly straightforward.

Fixes servo#2604. Pretty sure the issue with the other version mentioned
there was just that it held on to the lock too long.
eefriedman added a commit to eefriedman/servo that referenced this issue Sep 20, 2015
Making the Stylist usage threadsafe without unsafe code or extra locking
required some changes to WorkQueue; the changes are mostly straightforward.

Some refactoring of LayoutTaskData was also required: this is basically
just splitting the structure in two so the borrow checker can understand
that building a SharedLayoutContext only borrows part of LayoutTaskData.
The "frozen" part is the part that can't be safely modified while a parallel
work-queue is running.

Fixes servo#2604. Pretty sure the issue with the other version mentioned
there was just that it held on to the lock too long.
@Yoric
Copy link
Contributor

@Yoric Yoric commented Sep 29, 2015

I can try to work on this. How can I test this codepath?

Edit: Ah, I see that @eefriedman is on it. Nevermind.

@jdm
Copy link
Member

@jdm jdm commented Sep 29, 2015

I believe #7524 is taking care of this.

eefriedman added a commit to eefriedman/servo that referenced this issue Sep 29, 2015
Making the Stylist usage threadsafe without unsafe code or extra locking
required some changes to WorkQueue; the changes are mostly straightforward.

Some refactoring of LayoutTaskData was also required: this is basically
just splitting the structure in two so the borrow checker can understand
that building a SharedLayoutContext only borrows part of LayoutTaskData.
The "frozen" part is the part that can't be safely modified while a parallel
work-queue is running.

It might be worth considering switching to some sort of threadsafe
channel to avoid the mutexes... see Rust RFC PR servo#1299.

Fixes servo#2604. Pretty sure the issue with the other version mentioned
there was just that it held on to the lock too long.
eefriedman added a commit to eefriedman/servo that referenced this issue Sep 29, 2015
Making the Stylist usage threadsafe without unsafe code or extra locking
required some changes to WorkQueue; the changes are mostly straightforward.

Some refactoring of LayoutTaskData was also required: this is basically
just splitting the structure in two so the borrow checker can understand
that building a SharedLayoutContext only borrows part of LayoutTaskData.
The "frozen" part is the part that can't be safely modified while a parallel
work-queue is running.

It might be worth considering switching to some sort of threadsafe
channel to avoid the mutexes... see Rust RFC PR servo#1299.

Fixes servo#2604. Pretty sure the issue with the other version mentioned
there was just that it held on to the lock too long.
@Ms2ger
Copy link
Contributor

@Ms2ger Ms2ger commented Nov 7, 2015

I tried to just wrap it into Arc/Mutex on top of #8378; to my surprise it managed to load github: servo:master...Ms2ger:arc-stylist.

@eefriedman
Copy link
Contributor

@eefriedman eefriedman commented Nov 7, 2015

Sure, you can wrap it in a Mutex... but what does that do to the performance? (That's what sent me down the path of borrowing it.)

@Ms2ger
Copy link
Contributor

@Ms2ger Ms2ger commented Nov 8, 2015

Alternatively, we could try to move the Stylist out of the LayoutTask entirely; then we could borrow it while there's a mutable borrow of the LayoutTask.

@SimonSapin
Copy link
Member

@SimonSapin SimonSapin commented Nov 8, 2015

Move it tot the document node, similar to #8039 ?

@Ms2ger
Copy link
Contributor

@Ms2ger Ms2ger commented Nov 8, 2015

I don't follow.

@SimonSapin
Copy link
Member

@SimonSapin SimonSapin commented Nov 8, 2015

You mention moving Stylist out of LayoutTask. To where? One option could be to have it owned by the document node. There is sort of a precedent in that PR, which moves ownership of stylesheets from Stylist to respective DOM nodes.

@eefriedman
Copy link
Contributor

@eefriedman eefriedman commented Nov 8, 2015

If we intentionally want to dynamically check the borrowing of Stylist, I think we can just stuff it into an Arc, and use get_mut().unwrap() when we want to mutate it. Granted, it's stylistically terrible, but it's probably better than a raw pointer.

I don't see how changing the ownership of the Stylist helps.

@SimonSapin
Copy link
Member

@SimonSapin SimonSapin commented Nov 8, 2015

I don’t think we need dynamic checks at all if Stylist is in the DOM. Like the rest of DOM data, access is exclusive from the script task, and shared but read-only in the "early" phase (until flow tree construction) of layout.

@eefriedman
Copy link
Contributor

@eefriedman eefriedman commented Nov 8, 2015

Oh, right... if Stylist is in the DOM, we don't need to mutate it from layout. Makes sense.

@jdm
Copy link
Member

@jdm jdm commented Mar 10, 2016

Latest attempt at #7524.

@emilio
Copy link
Member

@emilio emilio commented Apr 23, 2016

#10815 Should take care of this.

It uses an Arc plus Arc::get_mut, and seems to work just fine. It should not have almost any performance overhead.

@SimonSapin
Copy link
Member

@SimonSapin SimonSapin commented Apr 23, 2016

@emilio Arc::get_mut clones the contents if the refcount is above one. Is this really desired here? This issue originally mentions RWLock.

@emilio
Copy link
Member

@emilio emilio commented Apr 23, 2016

@SimonSapin: Stylist is not cloneable, Arc::get_mut returns None if the refcount is not one (unlike Arc::make_mut).

I'm using Arc::get_mut(&mut rw_data.stylist).unwrap() and I haven't ever got a crash.

@SimonSapin
Copy link
Member

@SimonSapin SimonSapin commented Apr 23, 2016

Oh yeah, sorry, I got confused with make_mut. But if the refcount really is always one, could this be a Box?

@emilio
Copy link
Member

@emilio emilio commented Apr 23, 2016

I think not since it has to be handed out to layout traversal (I mean to SharedLayoutContext).

The refcount is always one when we update the stylist in the layout thread, but not always.

@emilio
Copy link
Member

@emilio emilio commented May 2, 2016

This is closed by #10815

@emilio emilio closed this May 2, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
10 participants
You can’t perform that action at this time.