kernel & libroot: Implement per-team unnamed semaphores.
This requires breaking syscall ABI to add the "flags" parameter to _kern_mutex_sem_release. Resolves a TODO.
This commit is contained in:
@@ -25,7 +25,7 @@ status_t _user_mutex_switch_lock(int32* fromMutex, uint32 fromFlags,
|
||||
int32* toMutex, const char* name, uint32 toFlags, bigtime_t timeout);
|
||||
status_t _user_mutex_sem_acquire(int32* sem, const char* name, uint32 flags,
|
||||
bigtime_t timeout);
|
||||
status_t _user_mutex_sem_release(int32* sem);
|
||||
status_t _user_mutex_sem_release(int32* sem, uint32 flags);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ extern status_t _kern_mutex_switch_lock(int32* fromMutex, uint32 fromFlags,
|
||||
bigtime_t timeout);
|
||||
extern status_t _kern_mutex_sem_acquire(int32* sem, const char* name,
|
||||
uint32 flags, bigtime_t timeout);
|
||||
extern status_t _kern_mutex_sem_release(int32* sem);
|
||||
extern status_t _kern_mutex_sem_release(int32* sem, uint32 flags);
|
||||
|
||||
/* sem functions */
|
||||
extern sem_id _kern_create_sem(int count, const char *name);
|
||||
|
||||
@@ -660,58 +660,43 @@ _user_mutex_sem_acquire(int32* sem, const char* name, uint32 flags,
|
||||
|
||||
syscall_restart_handle_timeout_pre(flags, timeout);
|
||||
|
||||
struct user_mutex_context* context;
|
||||
UserMutexContextFetcher contextFetcher(sem, flags);
|
||||
if (contextFetcher.InitCheck() != B_OK)
|
||||
return contextFetcher.InitCheck();
|
||||
struct user_mutex_context* context = contextFetcher.Context();
|
||||
|
||||
// TODO: use the per-team context when possible
|
||||
context = &sSharedUserMutexContext;
|
||||
|
||||
// wire the page and get the physical address
|
||||
VMPageWiringInfo wiringInfo;
|
||||
status_t error = vm_wire_page(B_CURRENT_TEAM, (addr_t)sem, true,
|
||||
&wiringInfo);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
UserMutexEntry* entry = get_user_mutex_entry(context, wiringInfo.physicalAddress);
|
||||
UserMutexEntry* entry = get_user_mutex_entry(context, contextFetcher.Address());
|
||||
if (entry == NULL)
|
||||
return B_NO_MEMORY;
|
||||
status_t error;
|
||||
{
|
||||
ReadLocker entryLocker(entry->lock);
|
||||
error = user_mutex_sem_acquire_locked(entry, sem,
|
||||
flags | B_CAN_INTERRUPT, timeout, entryLocker, true);
|
||||
flags | B_CAN_INTERRUPT, timeout, entryLocker, contextFetcher.IsWired());
|
||||
}
|
||||
put_user_mutex_entry(context, entry);
|
||||
|
||||
vm_unwire_page(&wiringInfo);
|
||||
return syscall_restart_handle_timeout_post(error, timeout);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
_user_mutex_sem_release(int32* sem)
|
||||
_user_mutex_sem_release(int32* sem, uint32 flags)
|
||||
{
|
||||
if (sem == NULL || !IS_USER_ADDRESS(sem) || (addr_t)sem % 4 != 0)
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
struct user_mutex_context* context;
|
||||
|
||||
// TODO: use the per-team context when possible
|
||||
context = &sSharedUserMutexContext;
|
||||
|
||||
// wire the page and get the physical address
|
||||
VMPageWiringInfo wiringInfo;
|
||||
status_t error = vm_wire_page(B_CURRENT_TEAM, (addr_t)sem, true,
|
||||
&wiringInfo);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
UserMutexContextFetcher contextFetcher(sem, flags);
|
||||
if (contextFetcher.InitCheck() != B_OK)
|
||||
return contextFetcher.InitCheck();
|
||||
struct user_mutex_context* context = contextFetcher.Context();
|
||||
|
||||
UserMutexEntry* entry = get_user_mutex_entry(context,
|
||||
wiringInfo.physicalAddress);
|
||||
contextFetcher.Address());
|
||||
{
|
||||
user_mutex_sem_release(entry, sem, true);
|
||||
user_mutex_sem_release(entry, sem, contextFetcher.IsWired());
|
||||
}
|
||||
put_user_mutex_entry(context, entry);
|
||||
|
||||
vm_unwire_page(&wiringInfo);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#define SEM_TYPE_NAMED 1
|
||||
#define SEM_TYPE_UNNAMED 2
|
||||
#define SEM_TYPE_UNNAMED_SHARED 3
|
||||
|
||||
|
||||
static int32
|
||||
@@ -114,7 +115,7 @@ sem_unlink(const char* name)
|
||||
int
|
||||
sem_init(sem_t* semaphore, int shared, unsigned value)
|
||||
{
|
||||
semaphore->type = SEM_TYPE_UNNAMED;
|
||||
semaphore->type = shared ? SEM_TYPE_UNNAMED_SHARED : SEM_TYPE_UNNAMED;
|
||||
semaphore->u.unnamed_sem = value;
|
||||
return 0;
|
||||
}
|
||||
@@ -123,7 +124,7 @@ sem_init(sem_t* semaphore, int shared, unsigned value)
|
||||
int
|
||||
sem_destroy(sem_t* semaphore)
|
||||
{
|
||||
if (semaphore->type != SEM_TYPE_UNNAMED)
|
||||
if (semaphore->type != SEM_TYPE_UNNAMED && semaphore->type != SEM_TYPE_UNNAMED_SHARED)
|
||||
RETURN_AND_SET_ERRNO(EINVAL);
|
||||
|
||||
return 0;
|
||||
@@ -138,7 +139,11 @@ unnamed_sem_post(sem_t* semaphore)
|
||||
if (oldValue > -1)
|
||||
return 0;
|
||||
|
||||
return _kern_mutex_sem_release(sem);
|
||||
uint32 flags = 0;
|
||||
if (semaphore->type == SEM_TYPE_UNNAMED_SHARED)
|
||||
flags |= B_USER_MUTEX_SHARED;
|
||||
|
||||
return _kern_mutex_sem_release(sem, flags);
|
||||
}
|
||||
|
||||
|
||||
@@ -162,6 +167,8 @@ unnamed_sem_timedwait(sem_t* semaphore, clockid_t clock_id,
|
||||
|
||||
bigtime_t timeoutMicros = B_INFINITE_TIMEOUT;
|
||||
uint32 flags = 0;
|
||||
if (semaphore->type == SEM_TYPE_UNNAMED_SHARED)
|
||||
flags |= B_USER_MUTEX_SHARED;
|
||||
if (timeout != NULL) {
|
||||
timeoutMicros = ((bigtime_t)timeout->tv_sec) * 1000000
|
||||
+ timeout->tv_nsec / 1000;
|
||||
|
||||
Reference in New Issue
Block a user