XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
#include "../NativePal.h"
#include <stdint.h>

// Private implementation of the small pthread ABI surface consumed by the
// official NativeAOT minipal/libunwind. No host pthread or Linux kernel is used.
// glibc x86_64 mutex storage is 40 bytes; this representation fits in it.
struct Mutex { uint64_t owner; uint32_t recursion,type,initialized; };
static_assert(sizeof(Mutex)<=40);
static uint64_t current() { auto p=XfeRuntimeGetPal();return p?p->current_thread_id():1; }
static void yield() { auto p=XfeRuntimeGetPal();if(!p){for(;;)__asm__ volatile("cli; hlt");}p->yield(); }

extern "C" int pthread_mutexattr_init(uint32_t* type) { if(!type)return 22;*type=0;return 0; }
extern "C" int pthread_mutexattr_destroy(uint32_t* type) { return type?0:22; }
extern "C" int pthread_mutexattr_settype(uint32_t* attr,int type) { if(!attr || type<0 || type>2)return 22;*attr=(uint32_t)type;return 0; }
extern "C" int pthread_mutex_init(Mutex* m,const uint32_t* attr) { if(!m)return 22;*m={0,0,attr?*attr:0,1};return 0; }
extern "C" int pthread_mutex_destroy(Mutex* m) { if(!m)return 22;if(__atomic_load_n(&m->owner,__ATOMIC_ACQUIRE))return 16;m->initialized=0;return 0; }
extern "C" int pthread_mutex_lock(Mutex* m)
{
    if(!m)return 22;
    uint64_t id=current();if(!id)return 22;
    for(;;){
        uint64_t owner=__atomic_load_n(&m->owner,__ATOMIC_ACQUIRE);
        if(owner==id){if(m->type!=1)return 35;if(m->recursion==UINT32_MAX)return 11;m->recursion++;return 0;}
        uint64_t expected=0;
        if(__atomic_compare_exchange_n(&m->owner,&expected,id,false,__ATOMIC_ACQUIRE,__ATOMIC_RELAXED)){m->recursion=1;return 0;}
        yield();
    }
}
extern "C" int pthread_mutex_unlock(Mutex* m)
{
    if(!m || __atomic_load_n(&m->owner,__ATOMIC_ACQUIRE)!=current() || !m->recursion)return 1;
    if(--m->recursion==0)__atomic_store_n(&m->owner,0,__ATOMIC_RELEASE);
    return 0;
}
extern "C" uint64_t pthread_self() { return current(); }

// A conservative rwlock serialises readers as well as writers. It preserves
// mutual exclusion/ordering and recursive reader acquisition, sacrificing
// reader parallelism. This kernel currently executes only one CPU.
struct RwLock { uint64_t owner;uint32_t recursion,write; };
static_assert(sizeof(RwLock)<=56);
static int rwlock(RwLock* lock,bool write)
{
    if(!lock)return 22;
    uint64_t id=current();if(!id)return 22;
    for(;;){
        uint64_t owner=__atomic_load_n(&lock->owner,__ATOMIC_ACQUIRE);
        if(owner==id){if(write||lock->write)return 35;if(lock->recursion==UINT32_MAX)return 11;lock->recursion++;return 0;}
        uint64_t expected=0;
        if(__atomic_compare_exchange_n(&lock->owner,&expected,id,false,__ATOMIC_ACQUIRE,__ATOMIC_RELAXED)){lock->recursion=1;lock->write=write;return 0;}
        yield();
    }
}
extern "C" int pthread_rwlock_rdlock(RwLock* lock) { return rwlock(lock,false); }
extern "C" int pthread_rwlock_wrlock(RwLock* lock) { return rwlock(lock,true); }
extern "C" int pthread_rwlock_unlock(RwLock* lock) { if(!lock || __atomic_load_n(&lock->owner,__ATOMIC_ACQUIRE)!=current() || !lock->recursion)return 1;if(--lock->recursion==0)__atomic_store_n(&lock->owner,0,__ATOMIC_RELEASE);return 0; }