head 1.6; access; symbols PTH_2_0_7:1.5 PTH_2_0_6:1.4 PTH_2_0_5:1.4 PTH_2_0_4:1.4 PTH_2_0_3:1.3 PTH_2_0_2:1.3 PTH_2_0_1:1.3 PTH_2_0_0:1.2 PTH_2_0b2:1.1 PTH_2_0b1:1.1 PTH_2_0b0:1.1; locks; strict; comment @ * @; 1.6 date 2007.01.01.18.23.53; author rse; state Exp; branches; next 1.5; commitid 9DhdiirNzQPBIP0s; 1.5 date 2006.06.08.17.54.54; author rse; state Exp; branches; next 1.4; commitid x8N3mLVdQgkbdeAr; 1.4 date 2004.12.31.19.34.45; author rse; state Exp; branches; next 1.3; 1.3 date 2004.07.13.10.50.49; author rse; state Exp; branches; next 1.2; 1.2 date 2003.01.01.15.49.12; author rse; state Exp; branches; next 1.1; 1.1 date 2002.11.03.09.59.33; author rse; state Exp; branches; next ; desc @@ 1.6 log @Adjusted all copyright messages for new year 2007. @ text @/* ** GNU Pth - The GNU Portable Threads ** Copyright (c) 1999-2007 Ralf S. Engelschall ** ** This file is part of GNU Pth, a non-preemptive thread scheduling ** library which can be found at http://www.gnu.org/software/pth/. ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public ** License as published by the Free Software Foundation; either ** version 2.1 of the License, or (at your option) any later version. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Lesser General Public License for more details. ** ** You should have received a copy of the GNU Lesser General Public ** License along with this library; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ** USA, or contact Ralf S. Engelschall . ** ** test_uctx.c: Pth test program (user-space context switching) */ /* ``Engineering does not require science. Science helps a lot, but people built perfectly good brick walls long before they knew why cement works.'' -- Alan Cox */ #include #include #include "pth.h" volatile pth_uctx_t uctx[10]; /* * Test 1: master and worker "threads" */ volatile int worker_done[10]; static void worker(void *ctx) { volatile int n = (int)ctx; volatile int i = 0; fprintf(stderr, "worker #%d: enter\n", n); for (i = 0; i < 100; i++) { fprintf(stderr, "worker #%d: working (step %d)\n", n, i); pth_uctx_switch(uctx[n], uctx[0]); } worker_done[n] = TRUE; fprintf(stderr, "worker #%d: exit\n", n); return; } static void test_working(void) { volatile int i; volatile int todo; fprintf(stderr, "master: startup\n"); fprintf(stderr, "master: create contexts\n"); pth_uctx_create((pth_uctx_t *)&uctx[0]); worker_done[0] = FALSE; for (i = 1; i < 10; i++) { worker_done[i] = FALSE; pth_uctx_create((pth_uctx_t *)&uctx[i]); pth_uctx_make(uctx[i], NULL, 32*1024, NULL, worker, (void *)i, uctx[0]); } do { todo = 0; for (i = 1; i < 10; i++) { if (!worker_done[i]) { fprintf(stderr, "master: switching to worker #%d\n", i); pth_uctx_switch(uctx[0], uctx[i]); fprintf(stderr, "master: came back from worker #%d\n", i); todo = 1; } } } while (todo); fprintf(stderr, "master: destroy contexts\n"); for (i = 1; i < 10; i++) pth_uctx_destroy(uctx[i]); pth_uctx_destroy(uctx[0]); fprintf(stderr, "master: exit\n"); return; } /* * Test 2: raw switching performance */ #define DO_SWITCHES 10000000 time_t stat_start; time_t stat_end; volatile int stat_switched; static void dummy(void *ctx) { while (1) { stat_switched++; pth_uctx_switch(uctx[1], uctx[0]); } return; } static void test_performance(void) { volatile int i; pth_uctx_create((pth_uctx_t *)&uctx[0]); pth_uctx_create((pth_uctx_t *)&uctx[1]); pth_uctx_make(uctx[1], NULL, 32*1024, NULL, dummy, NULL, uctx[0]); fprintf(stderr, "\n"); fprintf(stderr, "Performing %d user-space context switches... " "be patient!\n", DO_SWITCHES); stat_start = time(NULL); stat_switched = 0; for (i = 0; i < DO_SWITCHES; i++) { stat_switched++; pth_uctx_switch(uctx[0], uctx[1]); } stat_end = time(NULL); pth_uctx_destroy(uctx[0]); pth_uctx_destroy(uctx[1]); fprintf(stderr, "We required %d seconds for performing the test, " "so this means we can\n", (int)(stat_end-stat_start)); fprintf(stderr, "perform %d user-space context switches per second " "on this platform.\n", DO_SWITCHES/(int)(stat_end-stat_start)); fprintf(stderr, "\n"); return; } int main(int argc, char *argv[]) { test_working(); test_performance(); return 0; } @ 1.5 log @Adjusted all copyright messages for new year 2006 @ text @d3 1 a3 1 ** Copyright (c) 1999-2006 Ralf S. Engelschall @ 1.4 log @Adjusted all copyright messages for new year 2005. @ text @d3 1 a3 1 ** Copyright (c) 1999-2005 Ralf S. Engelschall @ 1.3 log @Adjusted all copyright messages for new year 2004. @ text @d3 1 a3 1 ** Copyright (c) 1999-2004 Ralf S. Engelschall @ 1.2 log @Adjusted all copyright messages for new year 2003. @ text @d3 1 a3 1 ** Copyright (c) 1999-2003 Ralf S. Engelschall @ 1.1 log @Added a stand-alone sub-API for manual user-space context switching. It is somewhat modeled after the POSIX ucontext(3) facility and consists of an opaque data type pth_uctx_t and the management functions pth_uctx_create(), pth_uctx_make(), pth_uctx_save(), pth_uctx_restore(), pth_uctx_switch() and pth_uctx_destroy(). These functions are based on the same underlying machine context switching facility (pth_mctx) the threads in GNU Pth are using. This facility can be used to implement co-routines without a full real multithreading environment or even to implement an own multithreading environment. @ text @d3 1 a3 1 ** Copyright (c) 1999-2002 Ralf S. Engelschall @