Skip to content

Commit 1b661e4

Browse files
committed
Release 8.2.11204
Change how the timers are handled. Instead of spawning a new thread every time a timer is fired, use a dedicated thread to handle all timer signals (SIGRTMIN). Signed-off-by: Brian Bian <brian.bian@intel.com>
1 parent 07d5ea1 commit 1b661e4

File tree

3 files changed

+94
-27
lines changed

3 files changed

+94
-27
lines changed

Common/Ver.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@
2020

2121
#define VER_MAJOR 8
2222
#define VER_MINOR 2
23-
#define VER_HOTFIX 11203
23+
#define VER_HOTFIX 11204
2424
#define VER_BUILD 9999

Common/esif_ccb_timer_lin_user.h

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include <signal.h>
2929

30+
typedef void (*esif_ccb_tmrm_cb_t)(esif_ccb_timer_handle_t cb_handle);
3031

3132
#pragma pack(push, 1)
3233

@@ -49,25 +50,17 @@ struct esif_timer_obj {
4950
esif_ccb_timer_handle_t timer_cb_handle;
5051
};
5152

53+
struct esif_tmrm_cb_obj {
54+
esif_ccb_tmrm_cb_t func;
55+
esif_ccb_timer_handle_t cb_handle;
56+
};
57+
5258
#pragma pack(pop)
5359

5460
static ESIF_INLINE void esif_ccb_timer_obj_disable_timer(
5561
struct esif_timer_obj *self
5662
);
5763

58-
59-
static ESIF_INLINE void esif_ccb_tmrm_cb_wrapper(
60-
const union sigval sv
61-
)
62-
{
63-
esif_ccb_timer_handle_t cb_handle = {0};
64-
65-
cb_handle = (esif_ccb_timer_handle_t) sv.sival_int;
66-
67-
esif_ccb_tmrm_callback(cb_handle);
68-
}
69-
70-
7164
static ESIF_INLINE enum esif_rc esif_ccb_timer_obj_create_timer(
7265
struct esif_timer_obj *self
7366
)
@@ -77,7 +70,6 @@ static ESIF_INLINE enum esif_rc esif_ccb_timer_obj_create_timer(
7770
return ESIF_OK;
7871
}
7972

80-
8173
static ESIF_INLINE enum esif_rc esif_ccb_timer_obj_enable_timer(
8274
struct esif_timer_obj *self,
8375
const esif_ccb_time_t timeout /* Timeout in msec */
@@ -86,19 +78,24 @@ static ESIF_INLINE enum esif_rc esif_ccb_timer_obj_enable_timer(
8678
enum esif_rc rc = ESIF_OK;
8779
struct sigevent se;
8880
struct itimerspec its;
89-
pthread_attr_t attr;
9081
u64 freq_nanosecs = timeout * 1000 * 1000; /* convert msec to nsec */
82+
struct esif_tmrm_cb_obj *cb_object_ptr = NULL;
9183

9284
ESIF_ASSERT(self != NULL);
9385

94-
pthread_attr_init(&attr);
95-
9686
esif_ccb_timer_obj_disable_timer(self);
9787

98-
se.sigev_notify = SIGEV_THREAD;
99-
se.sigev_notify_function = esif_ccb_tmrm_cb_wrapper;
100-
se.sigev_value.sival_int = self->timer_cb_handle;
101-
se.sigev_notify_attributes = &attr;
88+
cb_object_ptr = (struct esif_tmrm_cb_obj *) esif_ccb_malloc(sizeof(*cb_object_ptr));
89+
if (NULL == cb_object_ptr) {
90+
rc = ESIF_E_NO_MEMORY;
91+
goto exit;
92+
}
93+
cb_object_ptr->func = esif_ccb_tmrm_callback;
94+
cb_object_ptr->cb_handle = self->timer_cb_handle;
95+
96+
se.sigev_notify = SIGEV_SIGNAL;
97+
se.sigev_signo = SIGRTMIN;
98+
se.sigev_value.sival_ptr = cb_object_ptr;
10299

103100
if (0 != timer_create(CLOCK_REALTIME,
104101
&se,
@@ -117,7 +114,6 @@ static ESIF_INLINE enum esif_rc esif_ccb_timer_obj_enable_timer(
117114
goto exit;
118115
}
119116
exit:
120-
pthread_attr_destroy(&attr);
121117
return rc;
122118
}
123119

ESIF/Products/ESIF_UF/Sources/lin/main.c

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ static esif_thread_t g_udev_thread;
5353
static Bool g_udev_quit = ESIF_TRUE;
5454
static char *g_udev_target = NULL;
5555

56+
/* Dedicated thread to handle SIGRTMIN timer signals */
57+
static esif_thread_t g_sigrtmin_thread;
58+
5659
#define MAX_PAYLOAD 1024 /* max message size*/
5760

5861
static struct sockaddr_nl sock_addr_src, sock_addr_dest;
@@ -378,6 +381,52 @@ static void sigusr1_enable()
378381
sigaction(SIGUSR1, &action, NULL);
379382
}
380383

384+
static void sigrtmin_block(void)
385+
{
386+
/* Block SIGRTMIN; other threads created from the main thread
387+
* will inherit a copy of the signal mask.
388+
*/
389+
sigset_t set = {0};
390+
sigemptyset(&set);
391+
sigaddset(&set, SIGRTMIN);
392+
if (pthread_sigmask(SIG_BLOCK, &set, NULL)) {
393+
ESIF_TRACE_ERROR("Fail to block SIGRTMIN\n");
394+
}
395+
}
396+
397+
static void *sigrtmin_worker_thread(void *ptr)
398+
{
399+
sigset_t set = {0};
400+
siginfo_t info = {0};
401+
struct esif_tmrm_cb_obj *cb_object_ptr = NULL;
402+
403+
UNREFERENCED_PARAMETER(ptr);
404+
sigemptyset(&set);
405+
sigaddset(&set, SIGRTMIN);
406+
407+
while (1) { /* This thread will be canceled/killed after esif_uf_exit() */
408+
if (-1 == sigwaitinfo(&set, &info)) { /* sigwaitinfo is a cancellation point */
409+
ESIF_TRACE_ERROR("sigwaitinfo failed\n");
410+
continue;
411+
}
412+
413+
if (SIGRTMIN != info.si_signo) {
414+
ESIF_TRACE_ERROR("Received signal is not SIGRTMIN, ignore\n");
415+
continue;
416+
}
417+
418+
cb_object_ptr = (struct esif_tmrm_cb_obj *) info.si_value.sival_ptr;
419+
if (cb_object_ptr && cb_object_ptr->func) {
420+
cb_object_ptr->func(cb_object_ptr->cb_handle);
421+
cb_object_ptr->func = NULL;
422+
esif_ccb_free(cb_object_ptr);
423+
} else {
424+
ESIF_TRACE_ERROR("Invalid timer callback object: (obj=%p, func=%p)\n",
425+
cb_object_ptr, (cb_object_ptr ? cb_object_ptr->func : NULL));
426+
}
427+
}
428+
}
429+
381430
#if !defined(ESIF_ATTR_INSTANCE_LOCK)
382431
// Instance Checking Disabled in Android for now
383432

@@ -748,7 +797,10 @@ static int run_as_daemon(int start_with_pipe, int start_with_log, int start_in_b
748797
exit(EXIT_SUCCESS);
749798
}
750799

751-
/* 3. Call setsid (if background daemon) */
800+
/* 3. Block SIGRTMIN (will re-enable it in a dedicated thread) */
801+
sigrtmin_block();
802+
803+
/* 4. Call setsid (if background daemon) */
752804
if (start_in_background && -1 == setsid()) {
753805
printf("ESIF_UFD: setsid failed. Error #%d\n", errno);
754806
return ESIF_FALSE;
@@ -760,13 +812,13 @@ static int run_as_daemon(int start_with_pipe, int start_with_log, int start_in_b
760812
}
761813
sigterm_enable();
762814

763-
/* 4. Change to known directory. Performed in main */
764-
/* 5. Close all file descriptors incuding stdin, stdout, stderr */
815+
/* 5. Change to known directory. Performed in main */
816+
/* 6. Close all file descriptors incuding stdin, stdout, stderr */
765817
close(STDIN_FILENO); /* stdin */
766818
close(STDOUT_FILENO); /* stdout */
767819
close(STDERR_FILENO); /* stderr */
768820

769-
/* 6. Open file descriptors 0, 1, and 2 and redirect */
821+
/* 7. Open file descriptors 0, 1, and 2 and redirect */
770822
/* stdin */
771823
if (ESIF_TRUE == start_with_log) {
772824
unlink(cmd_out);
@@ -796,6 +848,9 @@ static int run_as_daemon(int start_with_pipe, int start_with_log, int start_in_b
796848
esif_ccb_thread_create(&g_thread, esif_event_worker_thread, "Daemon");
797849
}
798850

851+
/* Start the thread that handles SIGRTMIN */
852+
esif_ccb_thread_create(&g_sigrtmin_thread, sigrtmin_worker_thread, NULL);
853+
799854
#ifdef ESIF_FEAT_OPT_ACTION_SYSFS
800855
/* uevent listener */
801856
esif_udev_start();
@@ -893,6 +948,7 @@ static int run_as_server(FILE* input, char* command, int quit_after_command)
893948
if (!instance_lock()) {
894949
return ESIF_FALSE;
895950
}
951+
sigrtmin_block(); /* Block SIGRTMIN (will re-enable it in a dedicated thread) */
896952
sigterm_enable();
897953

898954
g_DataVaultStartScript = ESIF_STARTUP_SCRIPT_SERVER_MODE;
@@ -903,6 +959,9 @@ static int run_as_server(FILE* input, char* command, int quit_after_command)
903959
esif_ccb_sleep_msec(10);
904960
}
905961

962+
/* Start the thread that handles SIGRTMIN */
963+
esif_ccb_thread_create(&g_sigrtmin_thread, sigrtmin_worker_thread, NULL);
964+
906965
#ifdef ESIF_FEAT_OPT_ACTION_SYSFS
907966
/* uevent listener */
908967
esif_udev_start();
@@ -1167,6 +1226,18 @@ int main (int argc, char **argv)
11671226
/* Exit ESIF */
11681227
esif_uf_exit();
11691228

1229+
/* Stop and join the SIGRTMIN worker thread.
1230+
* All ESIF timers should have been canceled
1231+
* after esif_uf_exit() call, so it is safe
1232+
* to terminate the g_sigrtmin_thread now.
1233+
*/
1234+
#ifdef ESIF_ATTR_OS_ANDROID
1235+
pthread_kill(g_sigrtmin_thread, SIGRTMIN);
1236+
#else
1237+
pthread_cancel(g_sigrtmin_thread);
1238+
#endif
1239+
esif_ccb_thread_join(&g_sigrtmin_thread);
1240+
11701241
/* Release Instance Lock and exit*/
11711242
instance_unlock();
11721243
esif_main_exit();

0 commit comments

Comments
 (0)