The vcore abstraction gives user-space an abstraction of a physical core (within a virtual namespace) on top of which it can schedule its user-level threads. When running code associated with a vcore, we speak of being in vcore context.
Vcore context is analogous to the interrupt context in a traditional OS. Vcore context consists of a stack, a TLS, and a set of registers, much like a basic thread. It is the context in which a user-level scheduler makes its decisions and handles signals. Once a process leaves vcore context, usually by starting a user-level thread, any subsequent entrances to vcore context will be at the top of the stack at vcore_entry().
The vcore abstraction allows an application to manage its cores, schedule its threads, and get the best performance it possibly can from the hardware.
To access the vcore API, include the following header file:
#include <parlib/vcore.h>
#define LOG2_MAX_VCORES
#define MAX_VCORES
The log-base-2 of the maximum number of vcores supported on this platform
The maximum number of vcores supported on this platform
struct vcore;
typedef struct vcore vcore_t;
extern void vcore_entry();
User defined entry point for each vcore. If vcore_saved_ucontext is set, this function should just restore it, otherwise, it is user defined.
vcore_t *__vcores;
void **__vcore_tls_descs;
__thread ucontext_t vcore_context;
__thread ucontext_t *vcore_saved_ucontext;
__thread void *vcore_saved_tls_desc;
An array of pointers to the TLS descriptor for each vcore.
Context associated with each vcore. Serves as the entry point to this vcore whenever the vcore is first brough up, a usercontext yields on it, or a signal / async I/O notification is to be handled.
Current user context running on each vcore, used when interrupting a user context because of async I/O or signal handling. Vcore 0’s vcore_saved_ucontext is initialized to the continuation of the main thread’s context the first time it’s vcore_entry() function is invoked.
Current tls_desc of the user context running on each vcore, used when interrupting a user context because of async I/O or signal handling. Hard Thread 0’s vcore_saved_tls_desc is initialized to the tls descriptor of the main thread’s context the first time it’s vcore_entry() function is invoked.
int vcore_lib_init();
void vcore_reenter(void (*entry_func)(void));
int vcore_request(int k);
void vcore_yield();
int vcore_id(void);
size_t num_vcores(void);
size_t max_vcores(void);
bool in_vcore_context();
void clear_notif_pending(uint32_t vcoreid);
void enable_notifs(uint32_t vcoreid);
void disable_notifs(uint32_t vcoreid);
#define vcore_begin_access_tls_vars(vcoreid)
#define vcore_end_access_tls_vars()
#define vcore_set_tls_var(name, val)
#define vcore_get_tls_var(name)
Initialization routine for the vcore subsystem.
Function to reenter a vcore at the top of its stack.
Requests k additional vcores. Returns -1 if the request is impossible. Otherwise, blocks the calling vcore until the request is granted and returns 0.
Relinquishes the calling vcore.
Returns the id of the calling vcore.
Returns the current number of vcores allocated.
Returns the maximum number of allocatable vcores.
Returns whether you are currently running in vcore context or not.
Clears the flag for pending notifications
Enable Notifications
Disable Notifications
Begin accessing TLS variables associated with a specific vcore (possibly a different from the current one). Matched one-to-one with a following call to vcore_end_access_tls_vars() within the same function.
End access to a vcore’s TLS variables. Matched one-to-one with a previous call to vcore_begin_access_tls_vars() within the same function.
Set a single variable in the TLS of the current vcore. Mostly useful when running in uthread context and want to set something vcore specific.
Get a single variable from the TLS of the current vcore. Mostly useful when running in uthread context and want to get something vcore specific.