arm/atomic: round of atomic function changes
* change vint{32,64} to int{32,64} in:
* kernel implementation
* syscall definitions
* libroot prototypes
* update syscall functions with new atomic prototypes.
This commit is contained in:
@@ -13,19 +13,21 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int32 _user_atomic_set(vint32 *value, int32 newValue);
|
void _user_atomic_set(int32 *value, int32 newValue);
|
||||||
int32 _user_atomic_test_and_set(vint32 *value, int32 newValue, int32 testAgainst);
|
int32 _user_atomic_get_and_set(int32 *value, int32 newValue);
|
||||||
int32 _user_atomic_add(vint32 *value, int32 addValue);
|
int32 _user_atomic_test_and_set(int32 *value, int32 newValue, int32 testAgainst);
|
||||||
int32 _user_atomic_and(vint32 *value, int32 andValue);
|
int32 _user_atomic_add(int32 *value, int32 addValue);
|
||||||
int32 _user_atomic_or(vint32 *value, int32 orValue);
|
int32 _user_atomic_and(int32 *value, int32 andValue);
|
||||||
int32 _user_atomic_get(vint32 *value);
|
int32 _user_atomic_or(int32 *value, int32 orValue);
|
||||||
|
int32 _user_atomic_get(int32 *value);
|
||||||
|
|
||||||
int64 _user_atomic_set64(vint64 *value, int64 newValue);
|
void _user_atomic_set64(int64 *value, int64 newValue);
|
||||||
int64 _user_atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst);
|
int64 _user_atomic_get_and_set64(int64 *value, int64 newValue);
|
||||||
int64 _user_atomic_add64(vint64 *value, int64 addValue);
|
int64 _user_atomic_test_and_set64(int64 *value, int64 newValue, int64 testAgainst);
|
||||||
int64 _user_atomic_and64(vint64 *value, int64 andValue);
|
int64 _user_atomic_add64(int64 *value, int64 addValue);
|
||||||
int64 _user_atomic_or64(vint64 *value, int64 orValue);
|
int64 _user_atomic_and64(int64 *value, int64 andValue);
|
||||||
int64 _user_atomic_get64(vint64 *value);
|
int64 _user_atomic_or64(int64 *value, int64 orValue);
|
||||||
|
int64 _user_atomic_get64(int64 *value);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -494,23 +494,25 @@ extern status_t _kern_system_profiler_recorded(
|
|||||||
|
|
||||||
/* atomic_* ops (needed for CPUs that don't support them directly) */
|
/* atomic_* ops (needed for CPUs that don't support them directly) */
|
||||||
#ifdef ATOMIC_FUNCS_ARE_SYSCALLS
|
#ifdef ATOMIC_FUNCS_ARE_SYSCALLS
|
||||||
extern int32 _kern_atomic_set(vint32 *value, int32 newValue);
|
extern void _kern_atomic_set(int32 *value, int32 newValue);
|
||||||
extern int32 _kern_atomic_test_and_set(vint32 *value, int32 newValue,
|
extern int32 _kern_atomic_get_and_set(int32 *value, int32 newValue);
|
||||||
|
extern int32 _kern_atomic_test_and_set(int32 *value, int32 newValue,
|
||||||
int32 testAgainst);
|
int32 testAgainst);
|
||||||
extern int32 _kern_atomic_add(vint32 *value, int32 addValue);
|
extern int32 _kern_atomic_add(int32 *value, int32 addValue);
|
||||||
extern int32 _kern_atomic_and(vint32 *value, int32 andValue);
|
extern int32 _kern_atomic_and(int32 *value, int32 andValue);
|
||||||
extern int32 _kern_atomic_or(vint32 *value, int32 orValue);
|
extern int32 _kern_atomic_or(int32 *value, int32 orValue);
|
||||||
extern int32 _kern_atomic_get(vint32 *value);
|
extern int32 _kern_atomic_get(int32 *value);
|
||||||
#endif // ATOMIC_FUNCS_ARE_SYSCALLS
|
#endif // ATOMIC_FUNCS_ARE_SYSCALLS
|
||||||
|
|
||||||
#ifdef ATOMIC64_FUNCS_ARE_SYSCALLS
|
#ifdef ATOMIC64_FUNCS_ARE_SYSCALLS
|
||||||
extern int64 _kern_atomic_set64(vint64 *value, int64 newValue);
|
extern void _kern_atomic_set64(int64 *value, int64 newValue);
|
||||||
extern int64 _kern_atomic_test_and_set64(vint64 *value, int64 newValue,
|
extern int64 _kern_atomic_get_and_set64(int64 *value, int64 newValue);
|
||||||
|
extern int64 _kern_atomic_test_and_set64(int64 *value, int64 newValue,
|
||||||
int64 testAgainst);
|
int64 testAgainst);
|
||||||
extern int64 _kern_atomic_add64(vint64 *value, int64 addValue);
|
extern int64 _kern_atomic_add64(int64 *value, int64 addValue);
|
||||||
extern int64 _kern_atomic_and64(vint64 *value, int64 andValue);
|
extern int64 _kern_atomic_and64(int64 *value, int64 andValue);
|
||||||
extern int64 _kern_atomic_or64(vint64 *value, int64 orValue);
|
extern int64 _kern_atomic_or64(int64 *value, int64 orValue);
|
||||||
extern int64 _kern_atomic_get64(vint64 *value);
|
extern int64 _kern_atomic_get64(int64 *value);
|
||||||
#endif // ATOMIC64_FUNCS_ARE_SYSCALLS
|
#endif // ATOMIC64_FUNCS_ARE_SYSCALLS
|
||||||
|
|
||||||
/* System informations */
|
/* System informations */
|
||||||
|
|||||||
@@ -24,18 +24,24 @@
|
|||||||
* this is an acceptable compromise.
|
* this is an acceptable compromise.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int32
|
void
|
||||||
atomic_set(vint32 *value, int32 newValue)
|
atomic_set(int32 *value, int32 newValue)
|
||||||
{
|
{
|
||||||
InterruptsLocker locker;
|
InterruptsLocker locker;
|
||||||
|
|
||||||
int32 oldValue = *value;
|
|
||||||
*value = newValue;
|
*value = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
atomic_get_and_set(int32 *value, int32 newValue)
|
||||||
|
{
|
||||||
|
InterruptsLocker locker;
|
||||||
|
int32 oldValue = *value;
|
||||||
|
atomic_set(value, newValue);
|
||||||
return oldValue;
|
return oldValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
atomic_test_and_set(vint32 *value, int32 newValue, int32 testAgainst)
|
atomic_test_and_set(int32 *value, int32 newValue, int32 testAgainst)
|
||||||
{
|
{
|
||||||
InterruptsLocker locker;
|
InterruptsLocker locker;
|
||||||
|
|
||||||
@@ -46,7 +52,7 @@ atomic_test_and_set(vint32 *value, int32 newValue, int32 testAgainst)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
atomic_add(vint32 *value, int32 addValue)
|
atomic_add(int32 *value, int32 addValue)
|
||||||
{
|
{
|
||||||
InterruptsLocker locker;
|
InterruptsLocker locker;
|
||||||
|
|
||||||
@@ -56,7 +62,7 @@ atomic_add(vint32 *value, int32 addValue)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
atomic_and(vint32 *value, int32 andValue)
|
atomic_and(int32 *value, int32 andValue)
|
||||||
{
|
{
|
||||||
InterruptsLocker locker;
|
InterruptsLocker locker;
|
||||||
|
|
||||||
@@ -66,7 +72,7 @@ atomic_and(vint32 *value, int32 andValue)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
atomic_or(vint32 *value, int32 orValue)
|
atomic_or(int32 *value, int32 orValue)
|
||||||
{
|
{
|
||||||
InterruptsLocker locker;
|
InterruptsLocker locker;
|
||||||
|
|
||||||
@@ -76,7 +82,7 @@ atomic_or(vint32 *value, int32 orValue)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
atomic_get(vint32 *value)
|
atomic_get(int32 *value)
|
||||||
{
|
{
|
||||||
InterruptsLocker locker;
|
InterruptsLocker locker;
|
||||||
|
|
||||||
@@ -84,12 +90,27 @@ atomic_get(vint32 *value)
|
|||||||
return oldValue;
|
return oldValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32
|
void
|
||||||
_user_atomic_set(vint32 *value, int32 newValue)
|
_user_atomic_set(int32 *value, int32 newValue)
|
||||||
{
|
{
|
||||||
if (IS_USER_ADDRESS(value)
|
if (IS_USER_ADDRESS(value)
|
||||||
&& lock_memory((void *)value, sizeof(int32), B_READ_DEVICE) == B_OK) {
|
&& lock_memory((void *)value, sizeof(int32), B_READ_DEVICE) == B_OK) {
|
||||||
int32 oldValue = atomic_set(value, newValue);
|
atomic_set(value, newValue);
|
||||||
|
unlock_memory((void *)value, sizeof(int32), B_READ_DEVICE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
access_violation:
|
||||||
|
// XXX kill application
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
_user_atomic_get_and_set(int32 *value, int32 newValue)
|
||||||
|
{
|
||||||
|
if (IS_USER_ADDRESS(value)
|
||||||
|
&& lock_memory((void *)value, sizeof(int32), B_READ_DEVICE) == B_OK) {
|
||||||
|
int32 oldValue = atomic_get_and_set(value, newValue);
|
||||||
unlock_memory((void *)value, sizeof(int32), B_READ_DEVICE);
|
unlock_memory((void *)value, sizeof(int32), B_READ_DEVICE);
|
||||||
return oldValue;
|
return oldValue;
|
||||||
}
|
}
|
||||||
@@ -100,11 +121,11 @@ access_violation:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
_user_atomic_test_and_set(vint32 *value, int32 newValue, int32 testAgainst)
|
_user_atomic_test_and_set(int32 *value, int32 newValue, int32 testAgainst)
|
||||||
{
|
{
|
||||||
if (IS_USER_ADDRESS(value)
|
if (IS_USER_ADDRESS(value)
|
||||||
&& lock_memory((void *)value, sizeof(int32), B_READ_DEVICE) == B_OK) {
|
&& lock_memory((void *)value, sizeof(int32), B_READ_DEVICE) == B_OK) {
|
||||||
int32 oldValue = atomic_test_and_set(value, newValue, testAgainst);
|
int32 oldValue = atomic_test_and_set((int32*)value, newValue, testAgainst);
|
||||||
unlock_memory((void *)value, sizeof(int32), B_READ_DEVICE);
|
unlock_memory((void *)value, sizeof(int32), B_READ_DEVICE);
|
||||||
return oldValue;
|
return oldValue;
|
||||||
}
|
}
|
||||||
@@ -115,7 +136,7 @@ access_violation:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
_user_atomic_add(vint32 *value, int32 addValue)
|
_user_atomic_add(int32 *value, int32 addValue)
|
||||||
{
|
{
|
||||||
if (IS_USER_ADDRESS(value)
|
if (IS_USER_ADDRESS(value)
|
||||||
&& lock_memory((void *)value, sizeof(int32), B_READ_DEVICE) == B_OK) {
|
&& lock_memory((void *)value, sizeof(int32), B_READ_DEVICE) == B_OK) {
|
||||||
@@ -130,7 +151,7 @@ access_violation:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
_user_atomic_and(vint32 *value, int32 andValue)
|
_user_atomic_and(int32 *value, int32 andValue)
|
||||||
{
|
{
|
||||||
if (IS_USER_ADDRESS(value)
|
if (IS_USER_ADDRESS(value)
|
||||||
&& lock_memory((void *)value, sizeof(int32), B_READ_DEVICE) == B_OK) {
|
&& lock_memory((void *)value, sizeof(int32), B_READ_DEVICE) == B_OK) {
|
||||||
@@ -145,7 +166,7 @@ access_violation:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
_user_atomic_or(vint32 *value, int32 orValue)
|
_user_atomic_or(int32 *value, int32 orValue)
|
||||||
{
|
{
|
||||||
if (IS_USER_ADDRESS(value)
|
if (IS_USER_ADDRESS(value)
|
||||||
&& lock_memory((void *)value, sizeof(int32), B_READ_DEVICE) == B_OK) {
|
&& lock_memory((void *)value, sizeof(int32), B_READ_DEVICE) == B_OK) {
|
||||||
@@ -160,7 +181,7 @@ access_violation:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
_user_atomic_get(vint32 *value)
|
_user_atomic_get(int32 *value)
|
||||||
{
|
{
|
||||||
if (IS_USER_ADDRESS(value)
|
if (IS_USER_ADDRESS(value)
|
||||||
&& lock_memory((void *)value, sizeof(int32), B_READ_DEVICE) == B_OK) {
|
&& lock_memory((void *)value, sizeof(int32), B_READ_DEVICE) == B_OK) {
|
||||||
|
|||||||
@@ -30,8 +30,17 @@
|
|||||||
static spinlock atomic_lock = B_SPINLOCK_INITIALIZER;
|
static spinlock atomic_lock = B_SPINLOCK_INITIALIZER;
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
atomic_set64(int64 *value, int64 newValue)
|
||||||
|
{
|
||||||
|
SpinLocker locker(&atomic_lock);
|
||||||
|
|
||||||
|
*value = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int64
|
int64
|
||||||
atomic_set64(vint64 *value, int64 newValue)
|
atomic_get_and_set64(int64 *value, int64 newValue)
|
||||||
{
|
{
|
||||||
SpinLocker locker(&atomic_lock);
|
SpinLocker locker(&atomic_lock);
|
||||||
|
|
||||||
@@ -42,7 +51,7 @@ atomic_set64(vint64 *value, int64 newValue)
|
|||||||
|
|
||||||
|
|
||||||
int64
|
int64
|
||||||
atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst)
|
atomic_test_and_set64(int64 *value, int64 newValue, int64 testAgainst)
|
||||||
{
|
{
|
||||||
SpinLocker locker(&atomic_lock);
|
SpinLocker locker(&atomic_lock);
|
||||||
|
|
||||||
@@ -54,7 +63,7 @@ atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst)
|
|||||||
|
|
||||||
|
|
||||||
int64
|
int64
|
||||||
atomic_add64(vint64 *value, int64 addValue)
|
atomic_add64(int64 *value, int64 addValue)
|
||||||
{
|
{
|
||||||
SpinLocker locker(&atomic_lock);
|
SpinLocker locker(&atomic_lock);
|
||||||
|
|
||||||
@@ -65,7 +74,7 @@ atomic_add64(vint64 *value, int64 addValue)
|
|||||||
|
|
||||||
|
|
||||||
int64
|
int64
|
||||||
atomic_and64(vint64 *value, int64 andValue)
|
atomic_and64(int64 *value, int64 andValue)
|
||||||
{
|
{
|
||||||
SpinLocker locker(&atomic_lock);
|
SpinLocker locker(&atomic_lock);
|
||||||
|
|
||||||
@@ -76,7 +85,7 @@ atomic_and64(vint64 *value, int64 andValue)
|
|||||||
|
|
||||||
|
|
||||||
int64
|
int64
|
||||||
atomic_or64(vint64 *value, int64 orValue)
|
atomic_or64(int64 *value, int64 orValue)
|
||||||
{
|
{
|
||||||
SpinLocker locker(&atomic_lock);
|
SpinLocker locker(&atomic_lock);
|
||||||
|
|
||||||
@@ -87,7 +96,7 @@ atomic_or64(vint64 *value, int64 orValue)
|
|||||||
|
|
||||||
|
|
||||||
int64
|
int64
|
||||||
atomic_get64(vint64 *value)
|
atomic_get64(int64 *value)
|
||||||
{
|
{
|
||||||
SpinLocker locker(&atomic_lock);
|
SpinLocker locker(&atomic_lock);
|
||||||
return *value;
|
return *value;
|
||||||
@@ -95,11 +104,11 @@ atomic_get64(vint64 *value)
|
|||||||
|
|
||||||
|
|
||||||
int64
|
int64
|
||||||
_user_atomic_set64(vint64 *value, int64 newValue)
|
_user_atomic_get_and_set64(int64 *value, int64 newValue)
|
||||||
{
|
{
|
||||||
if (IS_USER_ADDRESS(value)
|
if (IS_USER_ADDRESS(value)
|
||||||
&& lock_memory((void *)value, sizeof(int64), B_READ_DEVICE) == B_OK) {
|
&& lock_memory((void *)value, sizeof(int64), B_READ_DEVICE) == B_OK) {
|
||||||
int64 oldValue = atomic_set64(value, newValue);
|
int64 oldValue = atomic_get_and_set64(value, newValue);
|
||||||
unlock_memory((void *)value, sizeof(int64), B_READ_DEVICE);
|
unlock_memory((void *)value, sizeof(int64), B_READ_DEVICE);
|
||||||
return oldValue;
|
return oldValue;
|
||||||
}
|
}
|
||||||
@@ -110,8 +119,24 @@ access_violation:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
_user_atomic_set64(int64 *value, int64 newValue)
|
||||||
|
{
|
||||||
|
if (IS_USER_ADDRESS(value)
|
||||||
|
&& lock_memory((void *)value, sizeof(int64), B_READ_DEVICE) == B_OK) {
|
||||||
|
atomic_set64(value, newValue);
|
||||||
|
unlock_memory((void *)value, sizeof(int64), B_READ_DEVICE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
access_violation:
|
||||||
|
// XXX kill application
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int64
|
int64
|
||||||
_user_atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst)
|
_user_atomic_test_and_set64(int64 *value, int64 newValue, int64 testAgainst)
|
||||||
{
|
{
|
||||||
if (IS_USER_ADDRESS(value)
|
if (IS_USER_ADDRESS(value)
|
||||||
&& lock_memory((void *)value, sizeof(int64), B_READ_DEVICE) == B_OK) {
|
&& lock_memory((void *)value, sizeof(int64), B_READ_DEVICE) == B_OK) {
|
||||||
@@ -127,7 +152,7 @@ access_violation:
|
|||||||
|
|
||||||
|
|
||||||
int64
|
int64
|
||||||
_user_atomic_add64(vint64 *value, int64 addValue)
|
_user_atomic_add64(int64 *value, int64 addValue)
|
||||||
{
|
{
|
||||||
if (IS_USER_ADDRESS(value)
|
if (IS_USER_ADDRESS(value)
|
||||||
&& lock_memory((void *)value, sizeof(int64), B_READ_DEVICE) == B_OK) {
|
&& lock_memory((void *)value, sizeof(int64), B_READ_DEVICE) == B_OK) {
|
||||||
@@ -143,7 +168,7 @@ access_violation:
|
|||||||
|
|
||||||
|
|
||||||
int64
|
int64
|
||||||
_user_atomic_and64(vint64 *value, int64 andValue)
|
_user_atomic_and64(int64 *value, int64 andValue)
|
||||||
{
|
{
|
||||||
if (IS_USER_ADDRESS(value)
|
if (IS_USER_ADDRESS(value)
|
||||||
&& lock_memory((void *)value, sizeof(int64), B_READ_DEVICE) == B_OK) {
|
&& lock_memory((void *)value, sizeof(int64), B_READ_DEVICE) == B_OK) {
|
||||||
@@ -159,7 +184,7 @@ access_violation:
|
|||||||
|
|
||||||
|
|
||||||
int64
|
int64
|
||||||
_user_atomic_or64(vint64 *value, int64 orValue)
|
_user_atomic_or64(int64 *value, int64 orValue)
|
||||||
{
|
{
|
||||||
if (IS_USER_ADDRESS(value)
|
if (IS_USER_ADDRESS(value)
|
||||||
&& lock_memory((void *)value, sizeof(int64), B_READ_DEVICE) == B_OK) {
|
&& lock_memory((void *)value, sizeof(int64), B_READ_DEVICE) == B_OK) {
|
||||||
@@ -175,7 +200,7 @@ access_violation:
|
|||||||
|
|
||||||
|
|
||||||
int64
|
int64
|
||||||
_user_atomic_get64(vint64 *value)
|
_user_atomic_get64(int64 *value)
|
||||||
{
|
{
|
||||||
if (IS_USER_ADDRESS(value)
|
if (IS_USER_ADDRESS(value)
|
||||||
&& lock_memory((void *)value, sizeof(int64), B_READ_DEVICE) == B_OK) {
|
&& lock_memory((void *)value, sizeof(int64), B_READ_DEVICE) == B_OK) {
|
||||||
|
|||||||
@@ -49,15 +49,22 @@ miss3: ldrex r12, [r0]
|
|||||||
bx lr
|
bx lr
|
||||||
FUNCTION_END(atomic_or)
|
FUNCTION_END(atomic_or)
|
||||||
|
|
||||||
/* int atomic_set(int *value, int setTo)
|
/* void atomic_set(int *value, int setTo)
|
||||||
*/
|
*/
|
||||||
FUNCTION(atomic_set):
|
FUNCTION(atomic_set):
|
||||||
|
str r1, [r0]
|
||||||
|
bx lr
|
||||||
|
FUNCTION_END(atomic_set)
|
||||||
|
|
||||||
|
/* int atomic_get_and_set(int *value, int setTo)
|
||||||
|
*/
|
||||||
|
FUNCTION(atomic_get_and_set):
|
||||||
miss4: ldrex r12, [r0]
|
miss4: ldrex r12, [r0]
|
||||||
strex r3, r1, [r0]
|
strex r3, r1, [r0]
|
||||||
teq r3, #0
|
teq r3, #0
|
||||||
bne miss4
|
bne miss4
|
||||||
bx lr
|
bx lr
|
||||||
FUNCTION_END(atomic_set)
|
FUNCTION_END(atomic_get_and_set)
|
||||||
|
|
||||||
/* int atomic_test_and_set(int *value, int setTo, int testValue)
|
/* int atomic_test_and_set(int *value, int setTo, int testValue)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -18,6 +18,13 @@ atomic_set(int32 *value, int32 newValue)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
atomic_get_and_set(int32 *value, int32 newValue)
|
||||||
|
{
|
||||||
|
return _kern_atomic_get_and_set(value, newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
atomic_test_and_set(int32 *value, int32 newValue, int32 testAgainst)
|
atomic_test_and_set(int32 *value, int32 newValue, int32 testAgainst)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user