#define _XOPEN_SOURCE 600
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <signal.h>
sigjmp_buf stack_overflow_guard;
char alter_stack[4096];
void sigsegv_handler(int sig) {
if (sig == SIGSEGV) {
/* Jump to catch block */
siglongjmp(stack_overflow_guard, sig);
}
}
void install_sigsegv_handler() {
/* Prepare alternating stack */
stack_t stk;
stk.ss_sp = alter_stack;
stk.ss_size = sizeof(alter_stack);
stk.ss_flags = 0;
if (sigaltstack(&stk, NULL) == -1) {
fprintf(stderr, "ERROR: Unable to setup alternative stack.\n");
exit(EXIT_FAILURE);
}
/* Register SIGSEGV handler */
struct sigaction act;
act.sa_handler = &sigsegv_handler;
sigfillset(&act.sa_mask);
act.sa_flags |= SA_ONSTACK;
if (sigaction(SIGSEGV, &act, NULL) == -1) {
fprintf(stderr, "ERROR: Unable to instal signal handler.\n");
exit(EXIT_FAILURE);
}
}
int trigger_stack_overflow(int a, int b, int c, int d, int e) {
return trigger_stack_overflow(a + 1, b + 1, c + 1, d + 1, e + 1) *
trigger_stack_overflow(a - 1, b - 1, c - 1, d - 1, e - 1);
}
int main() {
install_sigsegv_handler();
if (sigsetjmp(stack_overflow_guard, 0) == 0) {
printf("normal path, got: %d\n",
trigger_stack_overflow(0, 0, 0, 0, 0));
} else {
printf("stack overflow\n");
}
return EXIT_SUCCESS;
}
2011年8月8日 星期一
處理 Stack Overflow
直接看程式碼比較快:
2011年5月20日 星期五
LaTeX 與 Beamer
最近因為一些需要,必需使用 LaTeX 製作投影片,所以研究了一下 Beamer 的使用方法。其實寫起來並不困難,和一般的 LaTeX article 差不多。Beamer 的 document structure 如下:
接下來和 article 一樣,可以分為 section 與 subsection,而每一個 section 和 subsection 可以由若干個 frame 組成。
我們可以看到每個 frame 都會有一個 frametitle,也就是每一頁上方的標題。而下面就是該頁的內容。如果你要條列出各個要點,可以使用 itemize。
最後如果你需要顯示大綱,可以在 titlepage 下面加上:
不過因為要建立 tableofcontents 所以要執行 pdflatex 編譯你的投影片二次。這樣你就可以得到一個精美的投影片了。你可以在這裡下載到範例投影片與原始檔。
\documentclass{beamer}
\usetheme{Singapore} %% 這一個是佈景主題 (選用)
\begin{document}
\title{Title}
\author{Author Name}
\institute{Institute}
\frame{\titlepage} %% 顯示標題頁面
%% ... 其他內容 ...
\end{document}接下來和 article 一樣,可以分為 section 與 subsection,而每一個 section 和 subsection 可以由若干個 frame 組成。
\section{Section 1}
%% 如果你有需要,可以在這裡加上 \subsection{Subsection 1.1}
\begin{frame}
\frametitle{Frame 1.1}
\begin{itemize}
\item{Item 1}
\item{Item 2}
\end{itemize}
\end{frame}我們可以看到每個 frame 都會有一個 frametitle,也就是每一頁上方的標題。而下面就是該頁的內容。如果你要條列出各個要點,可以使用 itemize。
最後如果你需要顯示大綱,可以在 titlepage 下面加上:
\section*{Outlines}
\begin{frame}
\frametitle{Outlines}
\tableofcontents
\end{frame}不過因為要建立 tableofcontents 所以要執行 pdflatex 編譯你的投影片二次。這樣你就可以得到一個精美的投影片了。你可以在這裡下載到範例投影片與原始檔。
2011年4月30日 星期六
用 OpenMP 實作平行化的 Quicksort
OpenMP 和 Pthread 不同,我們沒有辦法很精確地控制有多少的 Thread 正在執行。所以如果要實作 Quicksort,我們不能直接使用 Recursion。相反地,我們必須引入 Threading Pool 的概念,讓各個 Thread 主動去某個工作清單拿工作。概念程式碼如下:
void quicksort_impl(sort_value_t array[],
stack_t *s,
size_t *busy_threads) {
int idle = 1;
size_t begin = 0;
size_t end = 0;
/* We should loop forever until everyone is idle */
while (1) {
while (idle) {
/* This thread is idling.
Try to get a new task from the stack. */
#pragma omp critical
if (!stack_empty(s)) {
/* Get the pending sort range, start work now! */
sort_range_t *range = stack_top(s);
begin = range->begin;
end = range->end;
stack_pop(s);
++*busy_threads;
idle = 0;
}
/* If everyone finished his work, then leave now ... */
if (*busy_threads == 0) {
return;
}
}
size_t size = end - begin;
if (size <= 50) {
sort_value_t *seg = array + begin;
/* Use backward insertion sort when the sort range is small */
size_t i, j;
for (i = 1; i < size; ++i) {
sort_value_t cur = seg[i];
/* Move the number backward if they are greater than cur */
for (j = i; j > 0 && seg[j - 1] > cur; --j) {
seg[j] = seg[j - 1];
}
seg[j] = cur;
}
/* Mark begin as end so that we can acquire next sort range */
begin = end;
#pragma omp critical
--*busy_threads;
idle = 1;
/* Finished our range continue to acquire next range */
continue;
}
/* Partition our range */
sort_value_t *seg = array + begin;
size_t pivot_index = rand() % size;
SWAP(seg[0], seg[pivot_index]);
sort_value_t pivot = seg[0];
size_t left = 1;
size_t right = size - 1;
while (left < right) {
while (seg[left] <= pivot && left < right) { left++; }
while (seg[right] >= pivot && left < right) { right--; }
SWAP(seg[left], seg[right]);
}
if (seg[left] > pivot) {
left--;
}
SWAP(seg[0], seg[left]);
/* Push left subrange to stack */
#pragma omp critical
{
sort_range_t range;
range.begin = begin;
range.end = begin + left;
stack_push(s, &range);
}
/* Continue to sort right subrange */
begin += left + 1;
}
}
void quicksort(sort_value_t array[], size_t size) {
size_t busy_threads = 0;
stack_t *s = stack_new();
sort_range_t all = { 0 , size };
stack_push(s, &all);
/* Run quicksort_impl in parallel */
#pragma omp parallel
quicksort_impl(array, s, &busy_threads);
stack_delete(s);
}
訂閱:
文章 (Atom)