thread/primitive: add platform wrappers for pause/yield instructions
This commit is contained in:
parent
8c934fbd2c
commit
1f6caaa242
@ -157,8 +157,9 @@ endif ()
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
list (APPEND UTIL_FILES
|
list (APPEND UTIL_FILES
|
||||||
thread/event.hpp
|
thread/event.hpp
|
||||||
thread/semaphore.hpp
|
|
||||||
thread/flag.hpp
|
thread/flag.hpp
|
||||||
|
thread/primitive.hpp
|
||||||
|
thread/semaphore.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if (LINUX)
|
if (LINUX)
|
||||||
|
@ -3,13 +3,13 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*
|
*
|
||||||
* Copyright 2018 Danny Robson <danny@nerdcruft.net>
|
* Copyright 2018-2019 Danny Robson <danny@nerdcruft.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CRUFT_UTIL_PARALLEL_QUEUE_HPP
|
#pragma once
|
||||||
#define CRUFT_UTIL_PARALLEL_QUEUE_HPP
|
|
||||||
|
|
||||||
#include "../maths.hpp"
|
#include "../maths.hpp"
|
||||||
|
#include "../thread/primitive.hpp"
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
@ -78,7 +78,7 @@ namespace cruft::parallel {
|
|||||||
|
|
||||||
// try to bump the write cursor to claim that slot
|
// try to bump the write cursor to claim that slot
|
||||||
if (uint32_t orig = curr; !m_write.compare_exchange_weak (orig, next)) {
|
if (uint32_t orig = curr; !m_write.compare_exchange_weak (orig, next)) {
|
||||||
asm volatile ("pause;");
|
pause ();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ namespace cruft::parallel {
|
|||||||
uint32_t orig = curr;
|
uint32_t orig = curr;
|
||||||
if (m_read.hi.compare_exchange_weak (orig, next))
|
if (m_read.hi.compare_exchange_weak (orig, next))
|
||||||
break;
|
break;
|
||||||
asm volatile ("pause;");
|
pause ();
|
||||||
} while (1);
|
} while (1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -132,7 +132,7 @@ namespace cruft::parallel {
|
|||||||
if (uint32_t orig = curr; m_read.lo.compare_exchange_weak (orig, next))
|
if (uint32_t orig = curr; m_read.lo.compare_exchange_weak (orig, next))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
asm volatile ("pause;");
|
pause ();
|
||||||
} while (1);
|
} while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,5 +156,3 @@ namespace cruft::parallel {
|
|||||||
} m_read;
|
} m_read;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
25
thread/primitive.hpp
Normal file
25
thread/primitive.hpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* Copyright 2019 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../platform.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace cruft {
|
||||||
|
inline void pause [[gnu::always_inline]] (void)
|
||||||
|
{
|
||||||
|
#ifdef PROCESSOR_AMD64
|
||||||
|
asm volatile ("pause");
|
||||||
|
#elif PROCESSOR_ARM
|
||||||
|
asm volatile ("yield");
|
||||||
|
#else
|
||||||
|
#error "Unhandled processor type"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
@ -3,11 +3,13 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*
|
*
|
||||||
* Copyright 2018 Danny Robson <danny@nerdcruft.net>
|
* Copyright 2018-2019 Danny Robson <danny@nerdcruft.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "spinlock.hpp"
|
#include "spinlock.hpp"
|
||||||
|
|
||||||
|
#include "primitive.hpp"
|
||||||
|
|
||||||
#include "../debug.hpp"
|
#include "../debug.hpp"
|
||||||
|
|
||||||
using cruft::thread::spinlock;
|
using cruft::thread::spinlock;
|
||||||
@ -35,7 +37,7 @@ spinlock::lock (void)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
while (held)
|
while (held)
|
||||||
__asm__ volatile ("pause");
|
pause ();
|
||||||
} while (true);
|
} while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,10 +3,11 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*
|
*
|
||||||
* Copyright 2018 Danny Robson <danny@nerdcruft.net>
|
* Copyright 2018-2019 Danny Robson <danny@nerdcruft.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ticketlock.hpp"
|
#include "ticketlock.hpp"
|
||||||
|
#include "primitive.hpp"
|
||||||
|
|
||||||
using cruft::thread::ticketlock;
|
using cruft::thread::ticketlock;
|
||||||
|
|
||||||
@ -25,7 +26,7 @@ ticketlock::lock (void)
|
|||||||
auto self = next++;
|
auto self = next++;
|
||||||
|
|
||||||
while (current != self)
|
while (current != self)
|
||||||
__asm__ volatile ("pause");
|
pause ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user