UMS Worker
A UMS worker thread is a regular pthread that has entered the UMS working mode.
Enter UMS working mode
A UMS worker thread is created by calling the ums_pthread_create()
function.
The function is implemented as follows:
53int ums_pthread_create(pthread_t *thread, ums_attr_t *ums_attr,
54 void *(*func)(void *), void *args)
55{
56 worker_proc_args_t *ums_args;
57
58 if (!ums_attr || !func) {
59 errno = EFAULT;
60 return -1;
61 }
62
63 ums_args = malloc(sizeof(*ums_args));
64 if (!ums_args)
65 return -1;
66
67 ums_args->completion_list = ums_attr->completion_list;
68 ums_args->func = func;
69 ums_args->args = args;
70
71 return pthread_create(thread,
72 ums_attr->pthread_attr,
73 worker_wrapper_routine,
74 ums_args);
75}
where worker_proc_args_t
is defined as
5typedef struct worker_proc_args_s {
6 ums_completion_list_t completion_list;
7 void *(*func)(void *);
8 void *args;
9} worker_proc_args_t;
The worker_wrapper_routine
is the routine executed by the newly created
pthread: it starts entering the UMS worker mode and then executing the user
specified function.
In particular:
11static pthread_key_t worker_key;
12static pthread_once_t worker_key_once = PTHREAD_ONCE_INIT;
13
14static inline int exit_ums_mode(void)
15{
16 return ioctl(UMS_FILENO, IOCTL_EXIT_UMS);
17}
18
19static void destroy_worker_key(void *args)
20{
21 free(args);
22 (void) exit_ums_mode();
23}
24
25static void create_worker_key(void)
26{
27 (void) pthread_key_create(&worker_key, destroy_worker_key);
28}
29
30static void *worker_wrapper_routine(void *args)
31{
32 worker_proc_args_t *worker_args = args;
33
34 struct enter_ums_mode_args ums_args = {
35 .flags = ENTER_UMS_WORK,
36 .ums_complist = worker_args->completion_list
37 };
38
39 (void) pthread_once(&worker_key_once, create_worker_key);
40
41 // enter ums mode and deschedule worker thread (suspend here)
42 if (enter_ums_mode(&ums_args)) {
43 free(args);
44 return NULL;
45 }
46
47 (void) pthread_setspecific(worker_key, args);
48
49 // worker thread is now active for scheduling
50 return worker_args->func(worker_args->args);
51}
The worker_key
contains the unique worker_wrapper_routine
argument
specific for each worker thread. When the user specified function calls
pthread_exit()
, returns or is cancelled because of a pthread_cancel()
request, the destructor routine destroy_worker_key
is called releasing
every resource associated with that UMS worker thread.
UMS worker yield
The yielding of a UMS worker thread is implemented as follows:
77int ums_thread_yield(void *scheduler_param)
78{
79 return ioctl(UMS_FILENO, IOCTL_UMS_YIELD, scheduler_param);
80}