12873ace1SIngo Weinhold /*
22873ace1SIngo Weinhold * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
32873ace1SIngo Weinhold * Distributed under the terms of the MIT License.
42873ace1SIngo Weinhold */
52873ace1SIngo Weinhold
62873ace1SIngo Weinhold #include <errno.h>
72873ace1SIngo Weinhold #include <signal.h>
82873ace1SIngo Weinhold #include <stdio.h>
92873ace1SIngo Weinhold #include <stdlib.h>
102873ace1SIngo Weinhold #include <signal.h>
112873ace1SIngo Weinhold #include <string.h>
122873ace1SIngo Weinhold
132873ace1SIngo Weinhold #include <OS.h>
142873ace1SIngo Weinhold
152873ace1SIngo Weinhold
162873ace1SIngo Weinhold static int64 sHandledSignals = 0;
172873ace1SIngo Weinhold
182873ace1SIngo Weinhold
192873ace1SIngo Weinhold static status_t
signal_pusher(void * data)202873ace1SIngo Weinhold signal_pusher(void* data)
212873ace1SIngo Weinhold {
222873ace1SIngo Weinhold team_info teamInfo;
232873ace1SIngo Weinhold get_team_info(B_CURRENT_TEAM, &teamInfo);
242873ace1SIngo Weinhold thread_id mainThread = teamInfo.team;
252873ace1SIngo Weinhold
262873ace1SIngo Weinhold while (true) {
272873ace1SIngo Weinhold send_signal(mainThread, SIGUSR1);
282873ace1SIngo Weinhold snooze(1000);
292873ace1SIngo Weinhold }
302873ace1SIngo Weinhold
312873ace1SIngo Weinhold return B_OK;
322873ace1SIngo Weinhold }
332873ace1SIngo Weinhold
342873ace1SIngo Weinhold
352873ace1SIngo Weinhold static void
signal_handler(int signal)362873ace1SIngo Weinhold signal_handler(int signal)
372873ace1SIngo Weinhold {
382873ace1SIngo Weinhold free(malloc(10));
392873ace1SIngo Weinhold sHandledSignals++;
402873ace1SIngo Weinhold }
412873ace1SIngo Weinhold
422873ace1SIngo Weinhold
432873ace1SIngo Weinhold int
main()442873ace1SIngo Weinhold main()
452873ace1SIngo Weinhold {
462873ace1SIngo Weinhold const int testSeconds = 2;
472873ace1SIngo Weinhold printf("Trying to provoke allocator deadlock in signal handler.\n");
482873ace1SIngo Weinhold printf("If successful test will finish in %d seconds...\n", testSeconds);
492873ace1SIngo Weinhold
502873ace1SIngo Weinhold // install signal handler
512873ace1SIngo Weinhold if (signal(SIGUSR1, signal_handler) == SIG_ERR) {
522873ace1SIngo Weinhold fprintf(stderr, "Error: Failed to install signal handler: %s\n",
532873ace1SIngo Weinhold strerror(errno));
542873ace1SIngo Weinhold exit(1);
552873ace1SIngo Weinhold }
562873ace1SIngo Weinhold
572873ace1SIngo Weinhold // start signal thread
582873ace1SIngo Weinhold thread_id signalThread = spawn_thread(&signal_pusher, "signal pusher",
592873ace1SIngo Weinhold B_NORMAL_PRIORITY, NULL);
602873ace1SIngo Weinhold resume_thread(signalThread);
612873ace1SIngo Weinhold
622873ace1SIngo Weinhold bigtime_t endTime = system_time() + 1000000 * (bigtime_t)testSeconds;
632873ace1SIngo Weinhold while (system_time() < endTime) {
642873ace1SIngo Weinhold const int allocationCount = 1000;
652873ace1SIngo Weinhold void* allocations[allocationCount];
662873ace1SIngo Weinhold for (int i = 0; i < allocationCount; i++)
672873ace1SIngo Weinhold allocations[i] = malloc(rand() % 50);
682873ace1SIngo Weinhold for (int i = 0; i < allocationCount; i++)
692873ace1SIngo Weinhold free(allocations[i]);
702873ace1SIngo Weinhold }
712873ace1SIngo Weinhold
722873ace1SIngo Weinhold kill_thread(signalThread);
732873ace1SIngo Weinhold snooze(1000);
742873ace1SIngo Weinhold
75*fc8aebcaSAlexander von Gluck IV printf("test successful, handled %" B_PRId64 " signals\n", sHandledSignals);
762873ace1SIngo Weinhold
772873ace1SIngo Weinhold return 0;
782873ace1SIngo Weinhold }
79