[NEW] Double-Checked Locking is Broken | cs go double – Vietnamnhanvan

cs go double: คุณกำลังดูกระทู้

Double-Checked Locking is Broken

by Hongbo Zhang

October 18, 2019

Double-checked locking is a software design pattern for
reducing the overhead of acquiring a lock.
The program checks locking criteria first,
and acquires the lock only if the check indicates that locking is required.

Lazy initialization is a commonly used tactic for delaying the object
initialization until the first time it is accessed.
In multi-threaded environments, initialization is usually not thread safe,
so locking is required to protect the critical section.
Since only the first access requires locking,
double-checked locking is used to avoid locking overhead of subsequent accesses.
However, on many languages and hardware, the design can be unsafe.

Single-threaded lazy initialization won’t work in multi-threading

If we were writing single-threaded code, we could write a lazy initialization
like this:

class

Foo

{

private

Helper

helper

=

null

;

public

Helper

getHelper

() {

if

(helper

==

null

) helper

= new

Helper

();

return

helper; } }

This code works for a single thread, but if the code is run in
multi-threaded environments,
two or more threads could find that helper is null at the same time,
and create multiple copies of Helper object.
This can even cause a memory leak in some languages, such as C++.

As shown in the graph above,
when threads either run concurrently on single processor (e.g., thread 1 and thread 2),
or run in parallel on different processors simultaneously (e.g. thread 3 and thread 4),
they can create multiple copies of helper.

Always-synchronized solution is slow

To fix this issue, we can simply add a lock to this critical section as follows,
so that only one thread can enter this critical section at a time.

class

Foo

{

private

Helper

helper

=

null

;

public

Helper

getHelper

() {

synchronized

(this) {

if

(helper

==

null

) helper

= new

Helper

();

return

helper; } } }

However, we only need this section of code to be synchronized for the first
thread access.
After the object is created, acquiring and releasing lock is unnecessary,
and they can have a huge performance impact.

What we want is something like this:

Only the first thread will enter the synchronized section and create the object.
Once the helper is initialized, all subsequent accesses can run in parallel
without synchronization.

Intuitively, we can come up with the following steps to do this job:

  1. Check if the object is initialized without locking.
    If it is, then return the object immediately.
  2. Acquire the lock and check again if the object is initialized.
    If another thread has previously grabbed the lock,
    the current thread can see the object is created, and return the object.
  3. Otherwise, the current thread will create the object and return.

With the guidelines above, we will get the following code:

class

Foo

{

private

Helper

helper

=

null

;

public

Helper

getHelper

() {

if

(helper

==

null

) {

// first check

synchronized

(this) {

if

(helper

==

null

)

// second check

helper

= new

Helper

(); } }

return

helper; } }

This tactic is called double-checked locking.

Double-checked locking is broken

However, this code is not guaranteed to work.

helper = new Helper() is not an atomic operation,
it consists of multiple instructions allocating space, initializing fields of the object,
and assigning address to helper.

In order to show what is really happening there,
we expand helper = new Helper() with some pseudocode
and inline the object initialization code.

class

Foo

{

private

Helper

helper

=

null

;

public

Helper

getHelper

() {

if

(helper

==

null

) {

synchronized

(this) {

if

(helper

==

null

) { ptr

=

allocate(); ptr.field1

=

initField1(); ptr.field2

=

initField2(); helper

=

ptr; } } }

return

helper; } }

In order to improve overall performance,
some compilers, memory systems, or processors may reorder the instructions,
like moving helper = ptr before initializing fields of the object.

class

Foo

{

private

Helper

helper

=

null

;

public

Helper

getHelper

() {

if

(helper

==

null

) {

synchronized

(this) {

if

(helper

==

null

) { ptr

=

allocate(); helper

=

ptr; ptr.field1

=

initField1(); ptr.field2

=

initField2(); } } }

return

helper; } }

This reordering is legal because there is no data dependency between helper = ptr
and the instructions for initializing fields.
However, this reordering, in some certain execution order,
could result in other threads seeing a non-null value of helper
but accessing uninitialized fields of the object.

Another fix is also broken

A memory barrier is a type of instruction that can make the compiler and processor
enforce the ordering, so that the instructions on one side of the memory barrier will
not be reordered to the other side of the barrier.

In order to enforce that object initialization new Helper() to execute before
assigning to helper,
some people came up with another fix with a synchronized to enforce ordering,
since synchronized is an implicit memory barrier that enforces the instructions
inside the synchronized section to be executed before exiting the section
(i.e., releasing the lock).

class

Foo

{

private

Helper

helper

=

null

;

public

Helper

getHelper

() {

if

(helper

==

null

) {

Helper

h;

synchronized

(this) { h

=

helper;

if

(h

==

null

)

synchronized

(this) { h

= new

Helper

(); } helper

=

h; } }

return

helper; } }

The purpose of second synchronized is only to create memory barrier,
since mutual exclusion is already enforced by the first synchronized.

The intuition is that the lock releasing would act as a memory barrier,
so that helper=h will not be executed until the initialization
in the synchronized section is done.

Unfortunately, the lock releasing is a one-way memory barrier on many processors.
It only enforces the instructions in the synchronized section
to be executed before lock is released.
The instruction helper=h behind the memory barrier could still be moved into
synchronized section and executed before the object initialization is done.

The expanded and reordered pseudocode should look like the following,
which will result in the same problem as the original version of double-checked locking.

class

Foo

{

private

Helper

helper

=

null

;

public

Helper

getHelper

() {

if

(helper

==

null

) {

Helper

h;

synchronized

(this) { h

=

helper;

if

(h

==

null

)

synchronized

(this) { ptr

=

allocate(); h

=

ptr; helper

=

h; ptr.field1

=

initField1(); ptr.field2

=

initField2(); } } }

return

helper; } }

Working Solutions

Explicit Memory Barrier

The previous fix with two synchronized sections does not work
because releasing a lock is an implicit “one-way” memory barrier.
It is possible to make the double-checked locking actually work with an
explicit memory barrier.
For example, Preshing has provided an implementation of double-checked locking with
std::atomic and std::atomic_thread_fence in C++ 11.

class

Foo

{

private

: std::atomic <Foo

*

> helper;

public

: Foo

*

get_helper

() { Foo

*

h

=

helper.load(std::memory_order_relaxed); std::atomic_thread_fence(std::memory_order_acquire);

//memory barrier

if

(h

==

nullptr

) { std::lock_guard<std::mutex> lock(m_init); h

=

helper.load(std::memory_order_relaxed);

if

(h

==

nullptr

) { h

= new

Helper; std::atomic_thread_fence(std::memory_order_release);

//memory barrier

helper.store(h, std::memory_order_relaxed); } }

return

h; } };

  • std::atomic_thread_fence(std::memory_order_acquire) guarantees that
    read/write operations after a memory barrier cannot be reordered with
    read operations before the memory barrier.
  • std::atomic_thread_fence(std::memory_order_release) guarantees that
    read/write operations before a memory barrier cannot be reordered with
    write operations after the memory barrier.
See also  ++ Vua trò chơi yugioh tập 139 cuộc đấu yugi bóng đêm \u0026 marik, triệu hồi rồng osiris | yougioh

The memory barriers guarantee that

  1. h loads the value from helper before starting object initialization.
  2. object initialization finishes before storing the value to helper.

Atomic Operation

An atomic operation will either happen completely, or it does not happen at all.
This is no intermediate state, so that the side effects of an atomic operation
will not be visible until the operation is complete.

In previous analysis, we have seen that h = new Helper() can be interleaved
because it is not an atomic operations.
If this operation is atomic, the double-checked locking will work.

Volatile

Since JDK 5, we can make reads and writes for any variable atomic by declaring
it as a volatile variable.
Every read of a volatile will invalidate cached value and
load it from main memory.
Every write of a volatile will update value in cache and
then flush out the cached value to main memory.

The “volatile” in Java also provides ordering guarantees,
which are the same guarantees atomic_thread_fence in C++ provides:

  • The read/write operations of other variables after a read from a volatile
    variable cannot be reordered before the read from the volatile variable.
  • The read/write operations of other variables before a write to a volatile
    variable cannot be reordered after the write to the volatile variable.

With this new feature, the double-checked locking issue is resolved by simply
declaring helper as a volatile variable.

class

Foo

{

private volatile

Helper

helper

=

null

;

public

Helper

getHelper

() {

if

(helper

==

null

) {

synchronized

(this) {

if

(helper

==

null

) helper

= new

Helper

(); } }

return

helper; } }

However, since all read and write operations of a volatile variable
triggers cache coherence protocol and accesses main memory,
it can be very slow.
An improvement can be done with a local variable, to reduce number of times
accessing volatile variable.

class

Foo

{

private volatile

Helper

helper

=

null

;

public

Helper

getHelper

() {

Helper

h

=

helper;

if

(h

==

null

) {

synchronized

(this) { h

=

helper;

if

(h

==

null

) { h

= new

Helper

(); helper

=

h; } } }

return

h; } }

In cases that the helper is already initialized,
this optimization can reduce one volatile read by returning the local variable.

32-bit Primitive Variables

Pugh et al. claimed that the double-checked locking can work safely for 32-bit
primitives.

class

Foo

{

private int

magicNumber

=

;

public int

getMagicNumber

() {

if

(magicNumber

==

) {

synchronized

(this) {

if

(magicNumber

==

) magicNumber

=

GetMagicNumber(); } }

return

helper; } }

However, this specific case highly depends on the Java memory model.
The C/C++ equivalent of the above code is not safe.
The Java documentation specifies that
read and write operations of most primitive variables
(except long and double since they are 64-bit) are atomic.
But it is still not completely clear why it is safe and
how it is different from volatile primitive variables.

Static Singleton

If the helper is static, i.e., all the instances of class Foo share the
same instance of helper, defining the helper in a static field of a separate
class will solve the problem.

class

Foo

{

private static class

HelperSingleton

{

public static final

Helper

helper

= new

Helper

(); }

public

Helper

getHelper

() {

return

HelperSingleton

.helper; } }

This is known as initialization-on-demand holder idiom,
which is considered as a safe and efficient concurrent lazy initialization
for all Java versions.

As the Java documentation specifies,
a lock is used to ensure synchronized access to object initialization status
(uninitialized/initializing/initialized/erroneous state).
However, if all subsequent references to the object requires lock synchronization,
it is just equivalent to the “always-synchronized” solution above.
Unfortunately, it is still unclear how Java provides an efficient
unsynchronized access to initialized objects.

Thread Local

Alexander Terekhov provided an implementation of double-checked locking using
thread local variables.

ThreadLocal is a variable where each thread will have its own copy of the
thread local variable.
Each thread can only access and modify its own copy of a thread local variable
independently of other threads.

A thread local can be used to maintain the state of “whether the state has gone
through the synchronized initialization or not”.
If a thread has gone through the synchronized initialization once,
it can be confident that that object is already initialized.

Inside the synchronized initialization section,
only the first thread will find the object is null and initialize the object.
All threads will then change their per-thread state
at the first synchronized access,
so that they will not enter the synchronized section again.

class

Foo

{

private static

ThreadLocal

perThreadState

= new

ThreadLocal

();

private

Helper

helper

=

null

;

public

Helper

getHelper

() {

if

(perThreadState.get()

==

null

) {

synchronized

{

if

(helper

==

null

) helper

= new

Helper

(); perThreadState.set(perThreadState); } }

return

helper; } }

Admittedly, this solution is slightly more costly
compared with the “ideal” design:
instead of having only the first thread enter the synchronized section
and initialize the object,
each thread is required to enter the synchronized section exactly once
and change its own per-thread state (i.e., the thread local variable)
to prevent future access of the synchronized section.
However, the performance in the long run is still acceptable.

Conclusion

The article discusses the problem of double-checked locking for lazy
initialization in multi-threaded environments.
It analyzes why some intuitive solutions do not work,
and also analyzed some working solutions.

Writing multi-threaded program is hard.
Writing correct and safe multi-threaded program is even harder.
When analyzing the correctness of multi-threaded programs,
it requires the considerations of multiple components,
including compilers, systems, and processors.
On the other hand, when designing compilers, systems, or processors,
one also needs to take into consideration commonly used design patterns.

Acknowledgement

I have referred following documents for code examples and explanations.
Code structures and variable names are modified for consistency in this post.

Hongbo Zhang is a first-year PhD student in computer science. He is interested in systems and computer architecture. He is also an okay archer shooting recurve bow.

See also  23Mania Recap: Nets มองหาการเทรด! Zion กลับมาลงแข่งไม่ได้สักที!! | shopee wikipedia

This is the course blog for CS 6120, the PhD-level compilers course in the computer science department at Cornell.
You can subscribe to posts on the blog with RSS.

[NEW] List of All CS:GO Ranks with 2021 Rank Distribution | cs go double – Vietnamnhanvan

Ranking System Guide

The CS:GO ranking system can be a confusing topic to tackle for new players to the game. You start off without a rank, and after a set number of matchmaking you’ll receive one relating to your skill. But what exactly does this rank mean? What decided it, and where can you go from there?

In this detailed guide, we’ll cover everything you need to know about CS:GO ranks including a list of all 18 ranks in the game and what you can do to rank up quicker. Use the buttons below to quickly jump to a section that you need help with:

Getting Your First Rank

Starting things off at the beginning is how to get your first rank in CS:GO matchmaking. To get your rank, you first need to be level 2 to queue for competitive. You can increase your level by playing the more casual game modes in CS:GO such as deathmatch and casual. Doing so will equip new players with the basic skills they need to play in the more serious matchmaking.

Once you’re level 2, you need to win 10 games of matchmaking to be placed into a rank. While you’re collecting these wins you’ll be classed as unranked. After you’ve won those 10 games, you’ll have earned your first rank. This will usually be somewhere on the lower rungs of the list of ranks, but could be higher if you’ve played some form of Counter-Strike before.

Silver I is the lowest rank you can receive, and The Global Elite is the highest rank in the game. From that you can see the flow of how the rank system works in CS:GO.

There’s no set time where you should earn any of the ranks. Generally speaking, though, beginner players should be somewhere in the Silver ranks, intermediate players should be high Gold Nova/low Master Guardian, and experienced players should be anywhere from Legendary Eagle to Global Elite.

Above is an image of all 18 ranks in the game.

How to Rank Up

Ranking up in CS:GO is simple, though the algorithm behind it isn’t. To put it plainly, the more matchmaking games you win the faster you’ll rank up. As you’d expect though, there is more that goes into it than just that. Here is what will influence the speed in which you rank up.

  • What ranks your teammates are. The lower their rank, the more elo (the value that dictates your rank) you’ll earn from a win.
  • What ranks your opponents are. The higher their rank, the more elo you’ll earn from a win.
  • The number of times in a game of matchmaking you are named the MVP.
  • The round difference of the competitive games you play. You’ll gain more elo by beating a team 16-1 than you would if you beat them 16-14. On the flip side, you’ll lose more elo if you get stomped by a team 16-1 than if you only narrowly lose 16-14.

This is what affects your rank in CS:GO, but what can you do to ensure you rank up quickly?

Well, the best way to rank up fast is to take the time to practise and hone your game. This means instead of jumping into match after match, take some time between them.

Tips to Rank Up Faster

If you’re stuck in a “rank plateau” (unable to move up in the rankings for a long time), or just want to progress through the ranks at a faster rate than you currently are, we have a collection of tips and suggestions to help you rank up.

1. Play With a Party

Playing with a friends in a party is a great way to assure that your teammates cooperate and want to win. Starting a solo game, or game with just a single friend, is like playing Russian Roulette – but instead of a bullet firing from a gun, it’s whether or not you’re queued with a griefer, bad player, or player who doesn’t want to play with your team.

By playing with your friends, you can assure that everyone has a microphone and wants to play with the team. You can employ strategies like rushes and executes together, and won’t have people running out onto bombsites alone with the bomb on terrorist side!

2. Don’t Play Again Straight After Losing

Often after losing a game, players immediately rush into another game straight after out of frustration, and hope to win back their lost elo. This is bad because you play a lot worse when frustated (you are less patient, more likely to annoy your teammates, less focused), and also (most imporantly) because you haven’t worked out what went wrong in the last game.

Instead of playing another game straight after losing a game, take a short break from competitive matches to work out what went wrong in the previous match. You can do this by watching back your game demo via the “Watch” option from the main menu. Below are some things you might realise went wrong in the previous game, and pointers/advice to improve:

  • If you were aiming badly: practice in an FFA or deathmatch server for 15-30 minutes before playing again.
  • If your teammates were the problem: this isn’t something you can always improve on, but ask some friends (who are good at CS:GO) to join you in your next match. If you don’t have any friends to join you, start sending friend requests to players that you get along with at the end of your future games!
  • If you never had a good weapon (like an AK-47, M4A4, or AWP): make sure you have proper eco rounds in the next game.
  • Other problems include: rushing too much on either side (yes, you can rush too much on T side), not playing with your team, and playing too passively (especially on T side).

3. Limit Your Map Pool

Everyone has a favorite map on CS:GO. One where they know a few more strats than they do for other maps, or a few more smoke lineups. It only makes sense then that if you’re trying to rank up as fast as possible then you should play these maps the majority of the time.

Even better, if you’re a master of one of the maps the community doesn’t play as often like Cobblestone or Train, then you’ll likely be playing against players who don’t know the map quite as well. This is just another small thing you can do to ensure you get the most matchmaking wins possible where you shine as much possible, thus accelerating your climbing of the CS:GO ranking system.

See also  SC2 - Maru vs. Zest - DreamHack SC2 Masters Summer: Season Finals - Group B | maru starcraft 2

4. Train Your Aim and Practice Grenades

Even after thousands of hours, players are still far from mastering CS:GO. There are lots of different aspects and skills required to be good at Counter-Strike (or any FPS), but there are a few crucial skills that you need to practice. Two of those skills are training your aim and practicing smoke grenades.

Aim is an important, perhaps even the most important, skill a player can have. Every role in the game requires a reasonable ability to aim in order to succeed. Entry-fraggers have to have amazing aim to out-aim players on bombsites, support players have to have good aim to trade the entry fraggers out, and lurkers have to have good aim to kill players in unexpected parts of the map.

There are many ways to train your aim, here are just a few:

  • Deathmatch and FFA Servers – join a casual deathmatch game, or FFA server from the community server browser and practice your aim here.
  • Aim Botz – this is a workshop map that has lots of bots that you can practice your aim on. You can change settings to make them move, give them armor, etc. You can use this map by going to https://steamcommunity.com/sharedfiles/filedetails/?id=243702660, clicking “Subscribe” (make sure you’re signed in), and then in the “Play” menu in CS:GO select “Workshop Maps”.
  • Retake Servers – via the community server browser you can join retake servers. Retake servers are servers that repeatedly put players in positions to retake, or defend a site (on CT or T) with the bomb planted. These servers allow players to practice situational aim on different maps, as FFA servers have players playing differently to how they usually would (e.g. playing more aggressively, getting killed from behind, players in parts of the map they wouldn’t usually be).

5. Improve Your Settings (Mouse, Graphics, etc)

Would a football player play with incorrectly sized studs? Or, a tennis player play without the perfect racket? No! There are lots of optimizations, changes, and personalized adjustments you can make to greatly improve your game and peripheral setup.

Firstly, make sure that you have HRTF enabled in your audio settings. HRTF allows you to better hear where sound comes from – this comes in especially handy when pinpointing footsteps that you’re not too sure of the exact location of.

Everyone has different optimal mouse settings, but there are a few things you can do to help find those optimal settings:

  • Enable raw input (in CS:GO mouse settings) – this makes the signals your mouse sends go directly to CS:GO, instead of being changed/slowed down by Windows or other applications.
  • Aim for a lower sensitivity – you can do this by lowering your sensitivity by 0.01 every few days until you find the best speed. A lower sensitivity means you can more accurately make small adjustments, like moving your crosshair slightly to the left to make sure you hit a headshot.
  • Have a good quality, big mousemat – this might not be possible if you don’t have the funds or room where your mouse is, but a larger mousemat means you have to pick up your mouse less, and a high quality mouse mat will make your mouse more accurate.

Most graphics settings don’t make all that much difference to how the game plays out, but a few can completely hinder your ability to play well. Here are our graphics settings tips:

  • Disable VSync, or “Wait for Vertical Sync” in the CS:GO graphics settings menu.
  • Remove the FPS cap in the CS:GO graphics settings menu. You can also do this with the fpsmax command.
  • Play in “Fullscreen” mode, not “Windowed” or “Fullscreen Windowed” (better FPS).
  • Turn off Motion Blur.
  • Enable Multicore Rendering.
  • If you are suffering from low FPS, the settings that will help the most are: FXAA Anti-Aliasing (Disabled), Multi Sampling Anti-Aliasing Mode (None) and Shader Detail (Low).


Are The Dualies Viable?


Taking a look at the dualies and talking about whether or not they’re viable, and what situations you might want to be using them in. DUAL WEILD THESE THINGS BAAAABBYYYYYY
Patreon ► https://www.patreon.com/voocsgo
2nd Channel ► https://www.youtube.com/2voocsgo
Twitch ► https://www.twitch.tv/voocsgo
Discord ► https://discord.gg/Dw6KbFy
Twitter ► https://www.twitter.com/voocsgo
Youtube ► https://www.youtube.com/voocsgo

นอกจากการดูบทความนี้แล้ว คุณยังสามารถดูข้อมูลที่เป็นประโยชน์อื่นๆ อีกมากมายที่เราให้ไว้ที่นี่: ดูเพิ่มเติม

Are The Dualies Viable?

МОМЕНТЫ ДОСТОЙНЫЕ ГРАФФИТИ CS:GO


Повысь свой FPS c HYPERPC: https://vk.cc/c8vHQf
Скидка 3% на все в HYPERPC: YouTubeBD68VB1Q

Для сотрудничества и контакта:
Мой ВК https://vk.com/fobosna
Группа ВК https://vk.com/foboscsgo
Instagram https://www.instagram.com/fobosac/
Стим https://steamcommunity.com/id/fobosac

00:00 Вступление и спонсор
02:30 Сам видос
16:45 Бонус

МОМЕНТЫ ДОСТОЙНЫЕ ГРАФФИТИ CS:GO
HYPERPC RTXON FPSИМЕЕТЗНАЧЕНИЕ

МОМЕНТЫ ДОСТОЙНЫЕ ГРАФФИТИ CS:GO

[FULLMATCH] DE_DUST 2 | NAVI VS BIG | BLAST PREMIER FALL FINAL 2021


500BROS CSGO
Theo dõi 500Bros trên Nimo TV nhé các bạn ơi ► NIMO TV: https://www.nimo.tv/500bros
Sản phẩm các bạn đang xem được sản xuất bởi 500BROS Studio.
► SUBSCRIBE: http://bit.ly/500sCSGO

Các kênh YOUTUBE của chúng tôi:
► 500Bros CS: GO: http://youtube.com/500bros
► 500Bros PUBG: http://youtube.com/500brosPUBG
► 500Bros Dota 2: http://youtube.com/500brosDota2

►WEBSITE: https://500bros.com
► FACEBOOK : https://facebook.com/500brosstudio
► YOUTUBE : http://youtube.com/500bros
► TWITCH : http://twitch.tv/500bros
► NIMO TV: https://www.nimo.tv/500bros

[FULLMATCH] DE_DUST 2 | NAVI VS BIG | BLAST PREMIER FALL FINAL 2021

MOE WINS $84K ON CSGODOUBLE (WITH SEAN GARES \u0026 STEEL)


https://www.youtube.com/user/moetv1337

MOE WINS $84K ON CSGODOUBLE (WITH SEAN GARES \u0026 STEEL)

(Green Hell) Bố Độ cần mẫn chăm sóc 3 đứa con Nhím, Rambo, KL7 trong rừng xanh và cái kết.


(Green Hell) Bố Độ cần mẫn chăm sóc 3 đứa con Nhím, Rambo, KL7 trong rừng xanh và cái kết.
\r
►Lịch Live:\r
22:1523:59 hàng ngày trên Youtube.\r
0:0103:00 hàng ngày trên: https://www.nimo.tv/mixi\r
(Chủ Nhật chỉ live bên nimo.tv/mixi vào 23:00 )\r
\r
\r
\r
► DONATE:\r
\r
http://unghotoi.com/mixigaming\r
https://streamlabs.com/mixigamingofficial\r
https://playerduo.com/mixigaming\r
https://qr.wescan.vn/Mixi\r
\r
►Trang web chính thức để các bạn xem lại video và livestream: https://mixigaming.com/\r
\r
► Fanpage chính thức: https://www.facebook.com/MixiGaming/\r
► Facebook cá nhân: https://www.facebook.com/dophung1989\r
► Instagram: https://www.instagram.com/dochet1989\r
► Link Discord giao lưu: https://discord.gg/xeSFUXk\r
► Link Group FB: https://www.facebook.com/groups/mixigaming/\r
► Email liên hệ: [email protected]\r
\r
\r
\r
► Shop game bản quyền số 1 Việt Nam: divineshop.vn\r
(Nhập Code: mixigaming để giảm 5% tất cả game Steam trên DivineShop)\r
\r
\r
\r
mixigaming pubg gameplay lien minh 2017 lmht liên minh,pubg,battleground,battlegrounds,mixigaming\r
Tags: Mixigaming, Mixi, Độ Tày, Streamer Mixigaming, Funny, Mixigaming Funny Stream, Funny Stream, Streamer Việt Nam, Stream Việt Nam, Stream Việt, PUBG, Player Unknown’s Battle Ground VN, PUBG VN, CSGO, CSGO VN, mixigaming talkshow, mixigaming green hell, mixigaming nhism rambo kl7

(Green Hell) Bố Độ cần mẫn chăm sóc 3 đứa con Nhím, Rambo, KL7 trong rừng xanh và cái kết.

นอกจากการดูบทความนี้แล้ว คุณยังสามารถดูข้อมูลที่เป็นประโยชน์อื่นๆ อีกมากมายที่เราให้ไว้ที่นี่: ดูวิธีอื่นๆWiki

ขอบคุณมากสำหรับการดูหัวข้อโพสต์ cs go double

Leave a Comment