From 71d4f989a28ee8664230ba565f84b6fb48d6d559 Mon Sep 17 00:00:00 2001 From: brothercomplex Date: Fri, 1 Nov 2019 22:10:12 +1000 Subject: [PATCH 1/8] attempt to convert to preemptive --- TCB.h | 2 +- a.out | Bin 0 -> 18024 bytes msgs_test.c | 8 ++++--- stack/CMakeLists.txt | 4 ++++ stack/direction.cpp | 22 +++++++++++++++++ stack/direction.h | 12 ++++++++++ stack/new.cpp | 18 ++++++++++++++ stack/stack.h | 23 ++++++++++++++++++ stack/tests/CMakeLists.txt | 5 ++++ stack/tests/stack.cpp | 8 +++++++ thread_test.c | 47 +------------------------------------ 11 files changed, 99 insertions(+), 50 deletions(-) create mode 100755 a.out create mode 100644 stack/CMakeLists.txt create mode 100644 stack/direction.cpp create mode 100644 stack/direction.h create mode 100644 stack/new.cpp create mode 100644 stack/stack.h create mode 100644 stack/tests/CMakeLists.txt create mode 100644 stack/tests/stack.cpp diff --git a/TCB.h b/TCB.h index ed7ce23..522618e 100644 --- a/TCB.h +++ b/TCB.h @@ -14,7 +14,7 @@ typedef struct TCB_t{ struct TCB_t *prev; }TCB_t; -void init_TCB (TCB_t *tcb, void *function, void *stackP, int stack_size) +void init_TCB (TCB_t *tcb, void (* function)(void), void *stackP, int stack_size) { memset(tcb,'\0', sizeof(TCB_t)); //wash rinse getcontext(&tcb->context); //have to get parent context, else snow forms on hell diff --git a/a.out b/a.out new file mode 100755 index 0000000000000000000000000000000000000000..c6331149f318c78605a05878e0195cb519de9a48 GIT binary patch literal 18024 zcmeHPdvILUc|R*zw!mg38ygg3;^ozmAzDlF1Gz-7D{JMeAd9svff1P7wRRMu6)uuhSV2 zpJ);D@q4jYCg!3%M`DWaQv_Ullz`9Stah7!r!yYqaMiLcsqHwv|aFiQ0o-?!}L$UhIO(#&77 zxM(IUj+epjDue%38T`j(@Q2Ibuav=4W$=5-;IT6JEoJa$%HVgD!IuN~;Ln+k04UX; z@0P)7Y(4mMrfUFroFK~oh`)uRPSpAoldq#!QM^<^#lMKZlojs3>MDx4wZb$9hZAu# zWrdQKX$rHmXQLU8BqM{-lod(#Y+N5p#3MbS?XigBmFD!tL&L)C3x|R`1uE!Qwg(1c z>C})Ii6oPWq!>wCDX}XQwW49viVFL8nEgXL%z;oeCI%x`e=0G$aibd~$yC!*}TQ(eu#>IxN&bIYt zvv+kq*X&)R@>{o>tANvWR9Wx`~6MO{F*BTwVih`+_r=y^1AeWtPW(&#xP zIoAaM$tC|4rfqA*gBYp`u}JfIUgh!QpfU8k$@ql6pH=&$S;07$PwM*{UHdeba5`nf z-3)?eZ8)`s)07R@RZ7;h4Y$WN#~K!p!sybhU;6dDzV2r+3ZH!gDy;2C{TN74A?u0S= zd^N4URm!bt1}k^PYW&tL_aR5+A!1IR${}5GC6#H3GI>IlFQqaqO(rK~c`21?Niumr zmKRZ(mLijn$?~~WrX|SaK3T4yGA%tO_sa68UX*FcF*zd3A5xi?8k2t_%kNT|mKc*k zS$>nsw6vJ?$?~tMOiPN%Mp^zBD$`P8(j&`1r!p-eCTnH+Ig|(Xp)6C=?>aLt-)3aq zG)CW=3ifo3S1mK_rjFeyV=R{VVH4dMxG%{1h;p}yW>!|VaS!*#2Y}5v-bEgJmJ*>aC zbrV=3y|ULBZJkS5BlEVkz!+=25`}C7nv@;F&(W$CD7&_?9@EJ?!Q9siB}9V9$b4hk z$fT!?Om8-`@hxL4F#YsNjNP;3vXMEKZ9SXI5o(N1R2P-Udb36*ST`1U%jiELB{IQ! zNyiNYSYYaDW#XujdFdc!vu}QmijNRf5N8hw z4+h|k&oGvmz|$QIGM1(dniMWBgl<(&n-3g+#}y4nWTs4_404FVCD72Z zG5Q`_QDu>?3_3Jzyfs2DxDdKv-OOgG)fs7XfNUN=VvlQtXZq9(7Xu#~>jI}z=fmV# z%o*9&p?GjU+HiUyLq8{o<_q);`M6lN5kB4yhNF%d_Ip1z#seQ|ui|v68DksC$^y1> zmCcI2490wQqto-#=U@_f08X7=M!h4!1rppx;5=}@kIc4wD{J#tuME{=+2E%%z|WC3 zUmoc1E_k6pT(5b{^V2$N(Agv&tUi5#%*o)KGF;kBu-ewIsz#ERmw|P?(vVYK4d+qi zAUQ%}D)LpLk&9+MuRohlT1s1DNJVZC0>@WT+ zmplD$auykHJxrosQliaT^w$tLME9fYV+BzPD)e^ElU0{NY;?-?%?WEMM*Q1k;3VXZ zR-FTeE4vJlFJs{@;yepZb^wsP-tz$(gsp?lu|F0#K`k+k1x{*uis-RGRu;ztC!VEU z5NgdeYF0h@6mgzjh;|wBLfeF)k~L*}QL(Wf7uE~L=r>--r5C{0Gw8tVYtv{Q-959< zA$K~XXY!IBjko>~6=gp}#6kTy<=>(F|H0D-Xd)PIeTb_52`a>p&G7o)VOV+neUh+w zT?bVf_Us=K13f^EKcGww5`G(Ssp`Des=&y1x9|7p>Ju~-jkjJ%wN3qJ=>{CkH{drU z;b_1|xZ`Id#Lx|RUzvP^@JE%&7oMU8j=be%j;c8Q?U`I|bUIh_oe6~6a=7pdlE2ty z=LfJO8;?7~c_>MR% zdBV|Tq~D4r;-bl8MDT{nb5kN23tu9di;Eqdo453MHurXmn>zzt?Va5lM31pK;BPnA zD;zBOdM+9t^hi}x={aPQ>3Ez(tf6Ei6i(r#8D8lTP*jV4dnVt*fj5vy zI{5kx9g#@51Yf>uBeSI1)aXgk%Q~tq78$XeAXc6iRbKNV+Ej!Jnos`t6()e=tMc=rR9aV91tr}XoOv?_40{yZ^fS*eRwCKes}FX73< z5%7cH)4TP2`&IYJ{&@!c82Go_`4zFe{%hbr3;sY6KP34S@1KD`2eB&SfyW0p@#+wV z=a=9u18+5Wmx9-YeBQ5$4SBmg;CF-npq-CA>5hQ+Jb16$c@-z6t_RpY@bAX;aV>ny z+pb*ak^+Dz*8Tx9kKvk;x@0n}3TSn(?aQpt$ z-QssQ`rY+yZcm%L4)Sg8YWZILGuSx@J5<$dn(cwv9+>Tc*&dkff!QAT1MC6)F&BSd z#`kO|-L74y7YQ=S9d9A{+ohhR3jUI2^LK3*=`ycjwV2@V+i2}ViTR(L%_U@6ueA02lw0Ku}8ynW9WvOX}Du0m`#jC^@i~K#mU7EfK1B@iAXh+Cj^@(}^jpx; zpKgusb>Nq1oabw0MTo1BalxNDpF*fUN*(xfmFS0I;8ZVvZ%ne3_TbNjFL|B)xgU5b z{~wp~wW8XC4ALA$V57ABlfYf5^lz@vf;Ljh{_~PQGagRkx~jk_9%tPCO4^?}zNe&} z^Jm1v2O4*_cMclhDiIG$f$LkQ)a0KAiMz!ka??c!`RotoTHvL=)Bl>5U#sN@w4qxx zeyzUo$Y*`<;@XbKrv&+alG5^XwNr9W2qO0buN4>0h|j-}^2&z&_aOSy19@kh|5)39 zSlfR@D;+Ll=M~@!X;3^$kmKR4GV-5G+$}!T{UG-~pt`W4^f`tG;ENEqKhif?xt{^~ zW{Imh?Y|ws7gk&-`2N7WEoJ1J;qao0ne)|-GV*^Waku!5UO4pY3VxvR6M7uwz6^Lj z)A+r5VIudSfWKMB{xcXCYOhDn0~}Xpw4F9>NA7jO&JroFov@K6;M5PbJ{yQ^tG0i) z9$!5SqPvWp?OJ}7{@7pc5yDQgjQl-X{;-y>*VX@J8TlV+`D2dj=t0b;~_4*!}=GUBC6(KEhR|PqqB>y8mz2_yWX_N9XON zp5lt;dA$H;J1r8oORD_!THdGQiv8JAMm`DLGt-Q?yA1waZU0ei-=}r|R^yX;yl!Hf z{Yfijr3VJQ{i1MA$h3w{`T8P-V>jW1IT%Z955>%|l}M({Pr)>#(){7&Gz>@I7_uT9p41JMY_nt+DmuhD8BQa@8&6mf?_fOb-JXu(j4qBUD#+i~*4FJfG7<}sg3gV^Ea9bVT6mH54knP1XCJ+? zue`~GysW*EAwB60g<*tCN>$B%LTYdxHH3zv{qTuq1uuqKcro)1V>adK`}d`^k3;t? zEIVZ4=VPY4kE7XAmh(g}!yoOPus%OWGrgRIYzeoaqO=wzyFNc}GxZcn7oI~HZbt^M zc@tbeKbJG*bqVh`@%ozeyOF`uM&5sZerHPWrzz1k4P{xM_knH%h9yH@pP%!Y^8OV> zWYXriC~iZJ_J-Jh-Vb1UrIuv>S&r!r@M*7!%e-&EG^q8-f0AMUH7xExhQ@^Td4GZF zNiE3rvp%=~n_9n3%ke%0Q{I0geOmfC^=X|+eM0`p#QPGO>SZ=_^Ut9SWRS7zd$b|x zS<{Cc0mpu8De)6zNQCuye}?IcEU2mT`aR^(=Y1TeKDsz;$yxt#@UUAUuOSlS=XL&n z7@YE4X8H3|~nU)E>(E;x35;nSjxigG;~&0jxUo + +#define STACK_DIRECTION_UP 11 +#define SDU STACK_DIRECTION_UP +#define STACK_DIRECTION_DOWN 12 +#define SDD STACK_DIRECTION_DOWN + +#endif \ No newline at end of file diff --git a/stack/new.cpp b/stack/new.cpp new file mode 100644 index 0000000..574a69a --- /dev/null +++ b/stack/new.cpp @@ -0,0 +1,18 @@ +#include "direction.h" +#include "stack.h" +void Stack::alloc(size_t size) { + stack = new char[size]; + size = size; + direction = getStackDirection(); + if (direction == SDU) top = stack; + else top = stack + (size*sizeof(char));; +} + +void Stack::free() { + if (stack == nullptr) return; + delete[] stack; + stack = nullptr; + top = nullptr; + size = 0; + direction = 0; +} diff --git a/stack/stack.h b/stack/stack.h new file mode 100644 index 0000000..29523b3 --- /dev/null +++ b/stack/stack.h @@ -0,0 +1,23 @@ +#ifndef STACK_STACK +#define STACK_STACK + +#include "direction.h" +#include + +class Stack { + public: + char * stack = nullptr; + char * top = nullptr; // points to top of stack + size_t size = 0; + int direction = 0; + void alloc(size_t size); + void free(); + class internal { + public: + int getStackDirection(int *addr); + }; + int getStackDirection(); + char * getStackDirectionAsString(); +}; + +#endif \ No newline at end of file diff --git a/stack/tests/CMakeLists.txt b/stack/tests/CMakeLists.txt new file mode 100644 index 0000000..0e8486c --- /dev/null +++ b/stack/tests/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.4.1) + +add_executable(test_stack stack.cpp) +target_link_libraries(test_stack stack) +add_custom_command( TARGET test_stack POST_BUILD COMMAND test_stack) diff --git a/stack/tests/stack.cpp b/stack/tests/stack.cpp new file mode 100644 index 0000000..29a4d0c --- /dev/null +++ b/stack/tests/stack.cpp @@ -0,0 +1,8 @@ +#include + +int main(void) { + Stack s = Stack(); + s.alloc(100); + s.free(); + return 0; +} diff --git a/thread_test.c b/thread_test.c index a0cf59d..7937c68 100644 --- a/thread_test.c +++ b/thread_test.c @@ -1,46 +1 @@ -/************************************************************* -* - Author: Denny Abraham Cheriyan, Adrin Peter Fernandes - Testing threads.h using infinite functions - -*/ - -#include "threads.h" - -void func1(){ - int i=0; - while(1){ - printf("Executing within func1\n"); - i+=1; - yield(); - printf("Func1 Value - %d\n", i); - } -} - -void func2(){ - int i=0; - while(1){ - printf("Executing within func2\n"); - i+=2; - yield(); - printf("Func2 Value - %d\n", i); - } -} - -void func3(){ - int i=0; - while(1){ - printf("Executing within func3\n"); - i+=3; - yield(); - printf("Func3 Value - %d\n", i); - } -} - -int main(){ - start_thread(func1); - start_thread(func2); - start_thread(func3); - run(); - return 0; -} \ No newline at end of file +g \ No newline at end of file From 8b923f7ea37c1999367b22450f3887817a4086b0 Mon Sep 17 00:00:00 2001 From: brothercomplex Date: Fri, 1 Nov 2019 22:12:43 +1000 Subject: [PATCH 2/8] attempt to convert to preemptive --- thread_test.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/thread_test.c b/thread_test.c index 7937c68..8e43476 100644 --- a/thread_test.c +++ b/thread_test.c @@ -1 +1,95 @@ -g \ No newline at end of file +/************************************************************* +* + Author: Denny Abraham Cheriyan, Adrin Peter Fernandes + Testing threads.h using infinite functions + +*/ + +#include "threads.h" +#include // sleep +#include // SIGCHLD +#include // clone +#include // wait +#include "stack/stack.h" // Stack +#include "stack/direction.cpp" // Stack +#include "stack/new.cpp" // Stack + +void thr1() { + while(1) { + printf("1 Hello World!\n"); + fflush(stdout); + sleep(1); + } +} + +void thr2() { + while(1) { + printf("2 Hello World!\n"); + fflush(stdout); + sleep(2); + } +} + +bool firstrun = false; +int YIELD_THREADX(void * arg) { + if (!firstrun) { + puts("FIRST RUN"); + firstrun = true; + run(); + } else { + puts("YIELDING"); + yield(); + } + return 0; +} + +int YIELD_THREAD(void * arg) { + while(1) { + Stack x = Stack(); + x.alloc(4096); + long int pid = clone(YIELD_THREADX, x.top, CLONE_VM|SIGCHLD, nullptr); + if (pid == -1) { + perror("THREAD_CREATE clone"); + } + sleep(5); + } + return 0; +} + +int THREAD_CREATE(void * nu) { + start_thread(thr1); + start_thread(thr2); + Stack x = Stack(); + x.alloc(4096); + puts("THREAD_CREATE starting YIELD_THREAD"); + long int pid = clone(YIELD_THREAD, x.top, CLONE_VM|SIGCHLD, nullptr); + if (pid == -1) { + perror("THREAD_CREATE clone"); + x.free(); + } + puts("THREAD_CREATE running threads"); + return 0; +} + +int main(){ + Stack x = Stack(); + x.alloc(4096); + puts("starting THREAD_CREATE"); + long int pid = clone(THREAD_CREATE, x.top, CLONE_VM|SIGCHLD, nullptr); + if (pid == -1) { + perror("clone"); + x.free(); + } + puts("waiting for THREAD_CREATE"); + if (waitid(P_PID, pid, nullptr, WEXITED) == -1) { + perror("waitid"); + x.free(); + return 0; + } + puts("waited for THREAD_CREATE"); + puts("sleeping for 10 seconds"); + sleep(10); + puts("slept for 10 seconds"); + x.free(); + return 0; +} \ No newline at end of file From 093173e70d04a5165470b8fe8f714d47d59bd3bb Mon Sep 17 00:00:00 2001 From: brothercomplex Date: Fri, 1 Nov 2019 23:03:24 +1000 Subject: [PATCH 3/8] use signal for now --- a.out | Bin 18024 -> 24848 bytes thread_test.c | 95 ------------------------ thread_test.cpp | 193 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 193 insertions(+), 95 deletions(-) delete mode 100644 thread_test.c create mode 100644 thread_test.cpp diff --git a/a.out b/a.out index c6331149f318c78605a05878e0195cb519de9a48..7d8c83c23bae2d3c2ee392ed72bfdaba98d8e124 100755 GIT binary patch literal 24848 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 // sleep -#include // SIGCHLD -#include // clone -#include // wait -#include "stack/stack.h" // Stack -#include "stack/direction.cpp" // Stack -#include "stack/new.cpp" // Stack - -void thr1() { - while(1) { - printf("1 Hello World!\n"); - fflush(stdout); - sleep(1); - } -} - -void thr2() { - while(1) { - printf("2 Hello World!\n"); - fflush(stdout); - sleep(2); - } -} - -bool firstrun = false; -int YIELD_THREADX(void * arg) { - if (!firstrun) { - puts("FIRST RUN"); - firstrun = true; - run(); - } else { - puts("YIELDING"); - yield(); - } - return 0; -} - -int YIELD_THREAD(void * arg) { - while(1) { - Stack x = Stack(); - x.alloc(4096); - long int pid = clone(YIELD_THREADX, x.top, CLONE_VM|SIGCHLD, nullptr); - if (pid == -1) { - perror("THREAD_CREATE clone"); - } - sleep(5); - } - return 0; -} - -int THREAD_CREATE(void * nu) { - start_thread(thr1); - start_thread(thr2); - Stack x = Stack(); - x.alloc(4096); - puts("THREAD_CREATE starting YIELD_THREAD"); - long int pid = clone(YIELD_THREAD, x.top, CLONE_VM|SIGCHLD, nullptr); - if (pid == -1) { - perror("THREAD_CREATE clone"); - x.free(); - } - puts("THREAD_CREATE running threads"); - return 0; -} - -int main(){ - Stack x = Stack(); - x.alloc(4096); - puts("starting THREAD_CREATE"); - long int pid = clone(THREAD_CREATE, x.top, CLONE_VM|SIGCHLD, nullptr); - if (pid == -1) { - perror("clone"); - x.free(); - } - puts("waiting for THREAD_CREATE"); - if (waitid(P_PID, pid, nullptr, WEXITED) == -1) { - perror("waitid"); - x.free(); - return 0; - } - puts("waited for THREAD_CREATE"); - puts("sleeping for 10 seconds"); - sleep(10); - puts("slept for 10 seconds"); - x.free(); - return 0; -} \ No newline at end of file diff --git a/thread_test.cpp b/thread_test.cpp new file mode 100644 index 0000000..88d3381 --- /dev/null +++ b/thread_test.cpp @@ -0,0 +1,193 @@ +/************************************************************* +* + Author: Denny Abraham Cheriyan, Adrin Peter Fernandes + Testing threads.h using infinite functions + +*/ + +#include "threads.h" +#include // sleep +#include // SIGCHLD +#include // clone +#include // wait +#include "stack/stack.h" // Stack +#include "stack/direction.cpp" // Stack +#include "stack/new.cpp" // Stack + +#include // std::this_thread +#include // std::chrono_literals + +using namespace std::chrono_literals; + +void thr1() { + while(1) { + printf("thr1 sleep for 2 seconds!\n"); + std::this_thread::sleep_for(2s); + printf("slept!\n"); + } +} + +void thr2() { + while(1) { + printf("thr2 sleep for 2 seconds!\n"); + std::this_thread::sleep_for(2s); + printf("slept!\n"); + } +} + +#include // exit(), EXIT_FAILURE, EXIT_SUCCESS +#include // sigaction() +#include // printf(), fprintf(), stdout, stderr, perror(), _IOLBF +#include // memset() +#include // ITIMER_REAL, ITIMER_VIRTUAL, ITIMER_PROF, struct itimerval, setitimer() +#include // true, false +#include // INT_MAX +#include + +class Timer { + public: + int type_ = 0; + void (*handler_) (int) = nullptr; + int ms_ = 0; + bool oneShot_ = true; + class Types { + public: + enum { + ITIMER_REAL, + ITIMER_VIRTUAL, + ITIMER_PROF + }; + } Types; + int timer_signal(int timer_type); + void set_timer(int type, void (*handler) (int), int ms, bool oneShot); + static void timer_handler (int signum); +}; + +int Timer::timer_signal(int timer_type) { + int sig; + + switch (timer_type) { + case ITIMER_REAL: + sig = SIGALRM; + break; + case ITIMER_VIRTUAL: + sig = SIGVTALRM; + break; + case ITIMER_PROF: + sig = SIGPROF; + break; + default: + fprintf(stderr, "ERROR: unknown timer type %d!\n", timer_type); + exit(EXIT_FAILURE); + } + + return sig; +} + +void Timer::set_timer(int type, void (*handler)(int), int ms, bool oneShot) { + type_ = type; + handler_ = handler; + ms_ = ms; + oneShot_ = oneShot; + printf("oneshot: %s\n", oneShot ? "true" : "false"); + struct itimerval timer; + struct sigaction sa; + + /* Install signal handler for the timer. */ + memset (&sa, 0, sizeof (sa)); + sa.sa_handler = handler; + sigaction (timer_signal(type), &sa, NULL); + + /* Configure the timer to expire after ms msec... */ + // convert ms to seconds and ms + + int milliseconds = ms; + int seconds = milliseconds; + if (seconds > 999) { + seconds /= 1000; + milliseconds -= seconds * 1000; + } else seconds = 0; + printf("ms = %d\nmilliseconds = %d\nseconds = %d\n", ms, milliseconds, seconds); + + assert(seconds <= 60); + + timer.it_value.tv_sec = seconds; + timer.it_value.tv_usec = milliseconds; + + if (oneShot) { + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 0; + } else { + timer.it_interval.tv_sec = seconds; + timer.it_interval.tv_usec = milliseconds; + } + if (setitimer (type, &timer, NULL) < 0) { + perror("Setting timer"); + exit(EXIT_FAILURE); + }; +} + +bool firstrun = false; + +Timer timer = Timer(); + +void Timer::timer_handler(int signum) { + static int count = 1; + if (!firstrun) { + fprintf (stderr, "> FIRST RUN timer ms = %d, count = %03d\n", timer.ms_, count++); + firstrun = true; + run(); + } else { + fprintf (stderr, "> YIELDING FIRST RUN timer ms = %d, count = %03d\n", timer.ms_, count++); + yield(); + } +} + +int YIELD_THREAD(void * arg) { + timer.set_timer(timer.Types.ITIMER_REAL, Timer::timer_handler, 1000, false); + while(1); + return 0; +} + +int THREAD_CREATE(void * nu) { + start_thread(thr1); + start_thread(thr2); + Stack x = Stack(); + x.alloc(4096); + puts("THREAD_CREATE starting YIELD_THREAD"); + long int pid = clone(YIELD_THREAD, x.top, CLONE_VM|SIGCHLD, nullptr); + if (pid == -1) { + perror("THREAD_CREATE clone"); + x.free(); + } + if (waitid(P_PID, pid, nullptr, WEXITED) == -1) { + perror("waitid"); + x.free(); + return 0; + } + x.free(); + return 0; +} + +int main(){ + /* Flush each printf() as it happens. */ + setvbuf(stdout, 0, _IOLBF, 0); + setvbuf(stderr, 0, _IOLBF, 0); + + Stack x = Stack(); + x.alloc(4096); + puts("starting THREAD_CREATE"); + long int pid = clone(THREAD_CREATE, x.top, CLONE_VM|SIGCHLD, nullptr); + if (pid == -1) { + perror("clone"); + x.free(); + } + puts("waiting for THREAD_CREATE"); + if (waitid(P_PID, pid, nullptr, WEXITED) == -1) { + perror("waitid"); + x.free(); + return 0; + } + x.free(); + return 0; +} \ No newline at end of file From afdc155127d6ceb97fa92872302242abb70e5d1e Mon Sep 17 00:00:00 2001 From: brothercomplex Date: Fri, 1 Nov 2019 23:20:19 +1000 Subject: [PATCH 4/8] use signal for now, fix typo --- a.out | Bin 24848 -> 24848 bytes thread_test.cpp | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/a.out b/a.out index 7d8c83c23bae2d3c2ee392ed72bfdaba98d8e124..09d89f79c459844a9ce0c3aace417c779a8d832f 100755 GIT binary patch delta 2495 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 Q+>~w?vQ@PXaLsZ24bHgQbpQYW diff --git a/thread_test.cpp b/thread_test.cpp index 88d3381..070133d 100644 --- a/thread_test.cpp +++ b/thread_test.cpp @@ -138,7 +138,7 @@ void Timer::timer_handler(int signum) { firstrun = true; run(); } else { - fprintf (stderr, "> YIELDING FIRST RUN timer ms = %d, count = %03d\n", timer.ms_, count++); + fprintf (stderr, "> YIELDING timer ms = %d, count = %03d\n", timer.ms_, count++); yield(); } } From 529040920d6be26a04b07608c16d3f69757c7476 Mon Sep 17 00:00:00 2001 From: brothercomplex Date: Fri, 1 Nov 2019 23:40:53 +1000 Subject: [PATCH 5/8] use signal for now, clean up a bit --- a.out | Bin 24848 -> 24912 bytes thread_test.cpp | 25 +++++++++++++------------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/a.out b/a.out index 09d89f79c459844a9ce0c3aace417c779a8d832f..e23e009bf6c974072c1fc24e7b8e767fd6ad7a83 100755 GIT binary patch delta 5234 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 DYPk7( diff --git a/thread_test.cpp b/thread_test.cpp index 070133d..435b046 100644 --- a/thread_test.cpp +++ b/thread_test.cpp @@ -22,6 +22,7 @@ using namespace std::chrono_literals; void thr1() { while(1) { printf("thr1 sleep for 2 seconds!\n"); + // sleep(2) resumes on recieving a caught signal std::this_thread::sleep_for(2s); printf("slept!\n"); } @@ -30,6 +31,7 @@ void thr1() { void thr2() { while(1) { printf("thr2 sleep for 2 seconds!\n"); + // sleep(2) resumes on recieving a caught signal std::this_thread::sleep_for(2s); printf("slept!\n"); } @@ -144,27 +146,21 @@ void Timer::timer_handler(int signum) { } int YIELD_THREAD(void * arg) { + // timer is per process, the process it is set in must exist in order to recieve a signal timer.set_timer(timer.Types.ITIMER_REAL, Timer::timer_handler, 1000, false); - while(1); + pause(); return 0; } int THREAD_CREATE(void * nu) { - start_thread(thr1); - start_thread(thr2); Stack x = Stack(); x.alloc(4096); puts("THREAD_CREATE starting YIELD_THREAD"); long int pid = clone(YIELD_THREAD, x.top, CLONE_VM|SIGCHLD, nullptr); - if (pid == -1) { - perror("THREAD_CREATE clone"); - x.free(); - } - if (waitid(P_PID, pid, nullptr, WEXITED) == -1) { - perror("waitid"); - x.free(); - return 0; - } + if (pid == -1) perror("THREAD_CREATE clone"); + // sleep for 1 second to allow for pause + sleep(1); + // a stack is not needed since the process pauses x.free(); return 0; } @@ -174,6 +170,8 @@ int main(){ setvbuf(stdout, 0, _IOLBF, 0); setvbuf(stderr, 0, _IOLBF, 0); + start_thread(thr1); + start_thread(thr2); Stack x = Stack(); x.alloc(4096); puts("starting THREAD_CREATE"); @@ -181,6 +179,7 @@ int main(){ if (pid == -1) { perror("clone"); x.free(); + return 0; } puts("waiting for THREAD_CREATE"); if (waitid(P_PID, pid, nullptr, WEXITED) == -1) { @@ -188,6 +187,8 @@ int main(){ x.free(); return 0; } + puts("waited for THREAD_CREATE"); x.free(); + pause(); return 0; } \ No newline at end of file From 31cd4a31f6cc1b83871341802ebe1d5a349945b8 Mon Sep 17 00:00:00 2001 From: brothercomplex Date: Sat, 2 Nov 2019 12:32:31 +1000 Subject: [PATCH 6/8] restructure, add make files --- .gitignore | 2 + CMakeLists.txt | 9 + Makefile | 35 ++++ README.md | 7 +- a.out | Bin 24912 -> 0 bytes {stack => libstack}/CMakeLists.txt | 1 + {stack => libstack}/direction.cpp | 4 +- .../include/internal}/direction.h | 0 {stack => libstack/include}/stack.h | 2 +- {stack => libstack}/new.cpp | 4 +- {stack => libstack}/tests/CMakeLists.txt | 0 {stack => libstack}/tests/stack.cpp | 0 libthread/CMakeLists.txt | 5 + libthread/TBC.cpp | 9 + TCB.h => libthread/include/internal/TCB.h | 15 +- libthread/include/internal/q.h | 20 ++ libthread/include/thread.h | 12 ++ libthread/q.cpp | 41 ++++ libthread/tests/CMakeLists.txt | 5 + libthread/tests/thread.cpp | 84 ++++++++ libthread/thread.cpp | 23 +++ libtimer/CMakeLists.txt | 4 + libtimer/include/timer.h | 36 ++++ libtimer/timer.cpp | 72 +++++++ cl-srv.c => others/cl-srv.c | 0 msgs.h => others/msgs.h | 0 msgs_test.c => others/msgs_test.c | 0 prod_cons.c => others/prod_cons.c | 0 q.c => others/q.c | 2 +- q_degug.c => others/q_degug.c | 0 read_write.c => others/read_write.c | 0 sem.h => others/sem.h | 2 +- q.h | 54 ----- thread_test.cpp | 194 ------------------ threads.h | 31 --- 35 files changed, 371 insertions(+), 302 deletions(-) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 Makefile delete mode 100755 a.out rename {stack => libstack}/CMakeLists.txt (79%) rename {stack => libstack}/direction.cpp (92%) rename {stack => libstack/include/internal}/direction.h (100%) rename {stack => libstack/include}/stack.h (93%) rename {stack => libstack}/new.cpp (89%) rename {stack => libstack}/tests/CMakeLists.txt (100%) rename {stack => libstack}/tests/stack.cpp (100%) create mode 100644 libthread/CMakeLists.txt create mode 100644 libthread/TBC.cpp rename TCB.h => libthread/include/internal/TCB.h (51%) create mode 100644 libthread/include/internal/q.h create mode 100644 libthread/include/thread.h create mode 100644 libthread/q.cpp create mode 100644 libthread/tests/CMakeLists.txt create mode 100644 libthread/tests/thread.cpp create mode 100644 libthread/thread.cpp create mode 100644 libtimer/CMakeLists.txt create mode 100644 libtimer/include/timer.h create mode 100644 libtimer/timer.cpp rename cl-srv.c => others/cl-srv.c (100%) rename msgs.h => others/msgs.h (100%) rename msgs_test.c => others/msgs_test.c (100%) rename prod_cons.c => others/prod_cons.c (100%) rename q.c => others/q.c (97%) rename q_degug.c => others/q_degug.c (100%) rename read_write.c => others/read_write.c (100%) rename sem.h => others/sem.h (95%) delete mode 100644 q.h delete mode 100644 thread_test.cpp delete mode 100644 threads.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..efe500e --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +debug +release \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..14aff19 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.4.1) +include_directories(libstack/include) +add_subdirectory(libstack) + +include_directories(libtimer/include) +add_subdirectory(libtimer) + +include_directories(libthread/include) +add_subdirectory(libthread) \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9127015 --- /dev/null +++ b/Makefile @@ -0,0 +1,35 @@ +debug_dir = debug +debug_dir_target = $(debug_dir)-$(wildcard $(debug_dir)) +debug_dir_present = $(debug_dir)-$(debug_dir) +debug_dir_absent = $(debug_dir)- +release_dir = release +release_dir_target = $(release_dir)-$(wildcard $(release_dir)) +release_dir_present = $(release_dir)-$(release_dir) +release_dir_absent = $(release_dir)- + +all: debug release + +debug: | $(debug_dir_target) build_debug + +release: | $(release_dir_target) build_release + +$(release_dir_present): + +$(release_dir_absent): + mkdir $(release_dir) + +$(debug_dir_present): + +$(debug_dir_absent): + mkdir $(debug_dir) + +build_debug: + cd ${debug_dir} ; cmake -DCMAKE_BUILD_TYPE=Debug .. ; make || exit +build_release: + cd ${release_dir} ; cmake -DCMAKE_BUILD_TYPE=Release .. ; make || exit + +.PHONY: all + +clean: + rm -rf $(debug_dir) + rm -rf $(release_dir) diff --git a/README.md b/README.md index 79e9856..4a5a9de 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,12 @@ # README # -Routines that will allow a program to run, with multiple threads, using NON-preemptive scheduling on most Unix/Linux operating systems. Contains implementation of custom semaphores, and sample programs to test threads and semaphores. +Routines that will allow a program to run, with multiple threads, using preemptive scheduling on most Unix/Linux operating systems. Contains implementation of custom semaphores, and sample programs to test threads and semaphores. ### Requirements ### * Ubuntu 14.04 -* gcc compiler +* g++ compiler ### To test threads library ### -1. gcc thread_test.c -2. ./a.out | head -40 \ No newline at end of file +1. make \ No newline at end of file diff --git a/a.out b/a.out deleted file mode 100755 index e23e009bf6c974072c1fc24e7b8e767fd6ad7a83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24912 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 diff --git a/stack/CMakeLists.txt b/libstack/CMakeLists.txt similarity index 79% rename from stack/CMakeLists.txt rename to libstack/CMakeLists.txt index 3615b04..8376cfe 100644 --- a/stack/CMakeLists.txt +++ b/libstack/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_minimum_required(VERSION 3.4.1) +include_directories(include) add_library(stack SHARED direction.cpp new.cpp) add_subdirectory(tests) diff --git a/stack/direction.cpp b/libstack/direction.cpp similarity index 92% rename from stack/direction.cpp rename to libstack/direction.cpp index 949a459..ccdd427 100644 --- a/stack/direction.cpp +++ b/libstack/direction.cpp @@ -1,5 +1,5 @@ -#include "direction.h" -#include "stack.h" +#include "include/stack.h" + int Stack::internal::getStackDirection(int *addr) { int fun_local; if (addr < &fun_local) { diff --git a/stack/direction.h b/libstack/include/internal/direction.h similarity index 100% rename from stack/direction.h rename to libstack/include/internal/direction.h diff --git a/stack/stack.h b/libstack/include/stack.h similarity index 93% rename from stack/stack.h rename to libstack/include/stack.h index 29523b3..dd9bd99 100644 --- a/stack/stack.h +++ b/libstack/include/stack.h @@ -1,7 +1,7 @@ #ifndef STACK_STACK #define STACK_STACK -#include "direction.h" +#include "internal/direction.h" #include class Stack { diff --git a/stack/new.cpp b/libstack/new.cpp similarity index 89% rename from stack/new.cpp rename to libstack/new.cpp index 574a69a..7c69721 100644 --- a/stack/new.cpp +++ b/libstack/new.cpp @@ -1,5 +1,5 @@ -#include "direction.h" -#include "stack.h" +#include "include/stack.h" + void Stack::alloc(size_t size) { stack = new char[size]; size = size; diff --git a/stack/tests/CMakeLists.txt b/libstack/tests/CMakeLists.txt similarity index 100% rename from stack/tests/CMakeLists.txt rename to libstack/tests/CMakeLists.txt diff --git a/stack/tests/stack.cpp b/libstack/tests/stack.cpp similarity index 100% rename from stack/tests/stack.cpp rename to libstack/tests/stack.cpp diff --git a/libthread/CMakeLists.txt b/libthread/CMakeLists.txt new file mode 100644 index 0000000..caddf51 --- /dev/null +++ b/libthread/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.4.1) + +add_library(thread SHARED TBC.cpp q.cpp thread.cpp) +target_link_libraries(thread stack timer) +add_subdirectory(tests) diff --git a/libthread/TBC.cpp b/libthread/TBC.cpp new file mode 100644 index 0000000..0ab2d1b --- /dev/null +++ b/libthread/TBC.cpp @@ -0,0 +1,9 @@ +#include "include/internal/TCB.h" + +void init_TCB (TCB_t *tcb, void (* function)(void), void *stackP, int stack_size) { + memset(tcb, '\0', sizeof(TCB_t)); //wash rinse + getcontext(&tcb->context); //have to get parent context, else snow forms on hell + tcb->context.uc_stack.ss_sp = stackP; + tcb->context.uc_stack.ss_size = (size_t) stack_size; + makecontext(&tcb->context, function, 0); //context cooked +} \ No newline at end of file diff --git a/TCB.h b/libthread/include/internal/TCB.h similarity index 51% rename from TCB.h rename to libthread/include/internal/TCB.h index 522618e..1de0037 100644 --- a/TCB.h +++ b/libthread/include/internal/TCB.h @@ -8,19 +8,10 @@ #include #include -typedef struct TCB_t{ +typedef struct TCB_t { struct TCB_t *next; ucontext_t context; struct TCB_t *prev; -}TCB_t; - -void init_TCB (TCB_t *tcb, void (* function)(void), void *stackP, int stack_size) -{ - memset(tcb,'\0', sizeof(TCB_t)); //wash rinse - getcontext(&tcb->context); //have to get parent context, else snow forms on hell - tcb->context.uc_stack.ss_sp = stackP; - tcb->context.uc_stack.ss_size = (size_t) stack_size; - makecontext(&tcb->context,function,0); //context cooked -} - +} TCB_t; +void init_TCB (TCB_t *tcb, void (* function)(void), void *stackP, int stack_size); \ No newline at end of file diff --git a/libthread/include/internal/q.h b/libthread/include/internal/q.h new file mode 100644 index 0000000..40cb783 --- /dev/null +++ b/libthread/include/internal/q.h @@ -0,0 +1,20 @@ +/************************************************************* +* + Author: Denny Abraham Cheriyan, Adrin Peter Fernandes + Contains functions to initialize, add, delete and rotate + a doubly linked circular queue + +*/ + +#include "TCB.h" +#include +#include + + +void InitQ(TCB_t **head); + +void AddQ(TCB_t **head, TCB_t *item); + +TCB_t * DelQ(TCB_t **head); + +void RotateQ(TCB_t **head); \ No newline at end of file diff --git a/libthread/include/thread.h b/libthread/include/thread.h new file mode 100644 index 0000000..a00d0ab --- /dev/null +++ b/libthread/include/thread.h @@ -0,0 +1,12 @@ +/************************************************************* +* + Author: Denny Abraham Cheriyan, Adrin Peter Fernandes + Contains functions to Start, Run and Yield to other threads + +*/ + +#include "internal/q.h" + +void start_thread(void (* function)(void)); +void run(); +void yield(); \ No newline at end of file diff --git a/libthread/q.cpp b/libthread/q.cpp new file mode 100644 index 0000000..07e96b3 --- /dev/null +++ b/libthread/q.cpp @@ -0,0 +1,41 @@ +#include "include/internal/q.h" + +void InitQ(TCB_t **head) { + *head = 0; +} + +void AddQ(TCB_t **head, TCB_t *item) { + if (*head == 0) { + //When the head pointer is null + *head = item; + (*head)->next = *head; + (*head)->prev = *head; + } else { + //When there is one or more nodes + (*head)->prev->next = item; + item->prev = (*head)->prev; + (*head)->prev = item; + item->next = *head; + } +} + +TCB_t * DelQ(TCB_t **head) { + if ((*head) == 0) + return 0; + TCB_t *temp = *head; + if ((*head)->next == *head) { + //When there is one node + *head = 0; + } else { + //When there are two or more nodes + *head = (*head)->next; + temp->prev->next = *head; + (*head)->prev = temp->prev; + } + return temp; +} + +void RotateQ(TCB_t **head) { + if (*head != 0) + (*head) = (*head)->next; +} \ No newline at end of file diff --git a/libthread/tests/CMakeLists.txt b/libthread/tests/CMakeLists.txt new file mode 100644 index 0000000..c0cd382 --- /dev/null +++ b/libthread/tests/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.4.1) + +add_executable(test_thread thread.cpp) +target_link_libraries(test_thread thread) +add_custom_command( TARGET test_thread POST_BUILD COMMAND test_thread) diff --git a/libthread/tests/thread.cpp b/libthread/tests/thread.cpp new file mode 100644 index 0000000..055cf33 --- /dev/null +++ b/libthread/tests/thread.cpp @@ -0,0 +1,84 @@ +/************************************************************* +* + Author: Denny Abraham Cheriyan, Adrin Peter Fernandes + Testing threads.h using infinite functions + +*/ + +#include +#include // sleep +#include // SIGCHLD +#include // clone +#include // wait +#include // std::this_thread +#include // std::chrono_literals + +#include +#include + +using namespace std::chrono_literals; + +void thr1() { + while(1) { + printf("thr1 sleep for 2 seconds!\n"); + // sleep(2) resumes on receiving a caught signal + std::this_thread::sleep_for(2s); + printf("slept!\n"); + } +} + +void thr2() { + while(1) { + printf("thr2 sleep for 2 seconds!\n"); + // sleep(2) resumes on receiving a caught signal + std::this_thread::sleep_for(2s); + printf("slept!\n"); + } +} + +bool firstrun = false; + +Timer timer = Timer(); + +void Timer::timer_handler(int signum) { + static int count = 1; + if (!firstrun) { + fprintf (stderr, "> FIRST RUN timer ms = %d, count = %03d\n", timer.ms_, count++); + firstrun = true; + run(); + } else { + fprintf (stderr, "> YIELDING timer ms = %d, count = %03d\n", timer.ms_, count++); + yield(); + } +} + +int YIELD_THREAD(void * arg) { + // timer is per process, the process it is set in must exist in order to recieve a signal + timer.set_timer(timer.Types.ITIMER_REAL, Timer::timer_handler, 1000, false); + pause(); + return 0; +} + +int main(){ + /* Flush each printf() as it happens. */ + setvbuf(stdout, 0, _IOLBF, 0); + setvbuf(stderr, 0, _IOLBF, 0); + + start_thread(thr1); + start_thread(thr2); + + Stack x = Stack(); + x.alloc(4096); + // start in a new process to prevent its signal handler from being modified once set + long int pid = clone(YIELD_THREAD, x.top, CLONE_VM|SIGCHLD, nullptr); + if (pid == -1) perror("YIELD_THREAD clone"); + // sleep for 1 second to allow for pause + sleep(1); + // a stack is not needed since the process pauses + x.free(); + // let threads to do something for 8 seconds + sleep(8); + puts("exiting"); + kill(pid, SIGTERM); + return 0; +} diff --git a/libthread/thread.cpp b/libthread/thread.cpp new file mode 100644 index 0000000..9991be7 --- /dev/null +++ b/libthread/thread.cpp @@ -0,0 +1,23 @@ +#include "include/thread.h" + +const int STACK_SIZE = 8192; +TCB_t *RunQ = 0; + +void start_thread(void (* function)(void)) { + void *stack = (void *) malloc(STACK_SIZE); + TCB_t *tcb = (TCB_t *) malloc(sizeof(TCB_t)); + init_TCB(tcb, function, stack, STACK_SIZE); + AddQ(&RunQ, tcb); +} + +void run() { + ucontext_t parent; + getcontext(&parent); + swapcontext(&parent, &(RunQ->context)); +} + +void yield() { + ucontext_t *current = &(RunQ->context); + RotateQ(&RunQ); + swapcontext(current, &(RunQ->context)); +} \ No newline at end of file diff --git a/libtimer/CMakeLists.txt b/libtimer/CMakeLists.txt new file mode 100644 index 0000000..c8db561 --- /dev/null +++ b/libtimer/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.4.1) + +add_library(timer SHARED timer.cpp) +#add_subdirectory(tests) diff --git a/libtimer/include/timer.h b/libtimer/include/timer.h new file mode 100644 index 0000000..8f2d5f7 --- /dev/null +++ b/libtimer/include/timer.h @@ -0,0 +1,36 @@ +// +// Created by brothercomplex on 2/11/19. +// + +#ifndef custom_threads_libtimer +#define FOREGROUND_SERVICE_TIMER_H + + +#include // exit(), EXIT_FAILURE, EXIT_SUCCESS +#include // sigaction() +#include // printf(), fprintf(), stdout, stderr, perror(), _IOLBF +#include // memset() +#include // ITIMER_REAL, ITIMER_VIRTUAL, ITIMER_PROF, struct itimerval, setitimer() +#include // true, false +#include // INT_MAX + +class Timer { +public: + int type_ = 0; + void (*handler_) (int) = nullptr; + int ms_ = 0; + bool oneShot_ = true; + class Types { + public: + enum { + ITIMER_REAL, + ITIMER_VIRTUAL, + ITIMER_PROF + }; + } Types; + int timer_signal(int timer_type); + void set_timer(int type, void (*handler) (int), int ms, bool oneShot); + static void timer_handler (int signum); +}; + +#endif //FOREGROUND_SERVICE_TIMER_H diff --git a/libtimer/timer.cpp b/libtimer/timer.cpp new file mode 100644 index 0000000..9c54d72 --- /dev/null +++ b/libtimer/timer.cpp @@ -0,0 +1,72 @@ +// +// Created by brothercomplex on 2/11/19. +// + +#include "include/timer.h" + +int Timer::timer_signal(int timer_type) { + int sig; + + switch (timer_type) { + case ITIMER_REAL: + sig = SIGALRM; + break; + case ITIMER_VIRTUAL: + sig = SIGVTALRM; + break; + case ITIMER_PROF: + sig = SIGPROF; + break; + default: + fprintf(stderr, "ERROR: unknown timer type %d!\n", timer_type); + exit(EXIT_FAILURE); + } + + return sig; +} + +void Timer::set_timer(int type, void (*handler)(int), int ms, bool oneShot) { + type_ = type; + handler_ = handler; + ms_ = ms; + oneShot_ = oneShot; + printf("oneshot: %s\n", oneShot ? "true" : "false"); + struct itimerval timer; + struct sigaction sa; + + /* Install signal handler for the timer. */ + memset (&sa, 0, sizeof (sa)); + sa.sa_handler = handler; + sigaction (timer_signal(type), &sa, NULL); + + /* Configure the timer to expire after ms msec... */ + // convert ms to seconds and ms + + int milliseconds = ms; + int seconds = milliseconds; + if (seconds > 999) { + seconds /= 1000; + milliseconds -= seconds * 1000; + } else seconds = 0; + printf("ms = %d\nmilliseconds = %d\nseconds = %d\n", ms, milliseconds, seconds); + + if (seconds > 60) { + puts("error: seconds must not be greater than 60 seconds"); + abort(); + } + + timer.it_value.tv_sec = seconds; + timer.it_value.tv_usec = milliseconds; + + if (oneShot) { + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 0; + } else { + timer.it_interval.tv_sec = seconds; + timer.it_interval.tv_usec = milliseconds; + } + if (setitimer (type, &timer, NULL) < 0) { + perror("Setting timer"); + exit(EXIT_FAILURE); + }; +} \ No newline at end of file diff --git a/cl-srv.c b/others/cl-srv.c similarity index 100% rename from cl-srv.c rename to others/cl-srv.c diff --git a/msgs.h b/others/msgs.h similarity index 100% rename from msgs.h rename to others/msgs.h diff --git a/msgs_test.c b/others/msgs_test.c similarity index 100% rename from msgs_test.c rename to others/msgs_test.c diff --git a/prod_cons.c b/others/prod_cons.c similarity index 100% rename from prod_cons.c rename to others/prod_cons.c diff --git a/q.c b/others/q.c similarity index 97% rename from q.c rename to others/q.c index 25c7f56..d2bb4ee 100644 --- a/q.c +++ b/others/q.c @@ -1,6 +1,6 @@ #include #include -#include +#include "libthread/include/internal/TCB.h" struct Node { int data; diff --git a/q_degug.c b/others/q_degug.c similarity index 100% rename from q_degug.c rename to others/q_degug.c diff --git a/read_write.c b/others/read_write.c similarity index 100% rename from read_write.c rename to others/read_write.c diff --git a/sem.h b/others/sem.h similarity index 95% rename from sem.h rename to others/sem.h index 0265fc9..1e77172 100644 --- a/sem.h +++ b/others/sem.h @@ -6,7 +6,7 @@ have to ensure that the P(sem) and V(sem) are atomic operations */ -#include "threads.h" +#include "libthread/include/thread.h" typedef struct Semaphore_t { int count; diff --git a/q.h b/q.h deleted file mode 100644 index e4ea14d..0000000 --- a/q.h +++ /dev/null @@ -1,54 +0,0 @@ -/************************************************************* -* - Author: Denny Abraham Cheriyan, Adrin Peter Fernandes - Contains functions to initialize, add, delete and rotate - a doubly linked circular queue - -*/ - -#include "TCB.h" -#include -#include - - -void InitQ(TCB_t **head){ - *head = 0; -} - -void AddQ(TCB_t **head, TCB_t *item){ - if(*head == 0){ - //When the head pointer is null - *head = item; - (*head)->next = *head; - (*head)->prev = *head; - } - else{ - //When there is one or more nodes - (*head)->prev->next = item; - item->prev = (*head)->prev; - (*head)->prev = item; - item->next = *head; - } -} - -TCB_t * DelQ(TCB_t **head){ - if((*head) == 0) - return 0; - TCB_t *temp = *head; - if((*head)->next == *head){ - //When there is one node - *head = 0; - } - else { - //When there are two or more nodes - *head = (*head)->next; - temp->prev->next = *head; - (*head)->prev = temp->prev; - } - return temp; -} - -void RotateQ(TCB_t **head){ - if(*head != 0) - (*head) = (*head)->next; -} \ No newline at end of file diff --git a/thread_test.cpp b/thread_test.cpp deleted file mode 100644 index 435b046..0000000 --- a/thread_test.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/************************************************************* -* - Author: Denny Abraham Cheriyan, Adrin Peter Fernandes - Testing threads.h using infinite functions - -*/ - -#include "threads.h" -#include // sleep -#include // SIGCHLD -#include // clone -#include // wait -#include "stack/stack.h" // Stack -#include "stack/direction.cpp" // Stack -#include "stack/new.cpp" // Stack - -#include // std::this_thread -#include // std::chrono_literals - -using namespace std::chrono_literals; - -void thr1() { - while(1) { - printf("thr1 sleep for 2 seconds!\n"); - // sleep(2) resumes on recieving a caught signal - std::this_thread::sleep_for(2s); - printf("slept!\n"); - } -} - -void thr2() { - while(1) { - printf("thr2 sleep for 2 seconds!\n"); - // sleep(2) resumes on recieving a caught signal - std::this_thread::sleep_for(2s); - printf("slept!\n"); - } -} - -#include // exit(), EXIT_FAILURE, EXIT_SUCCESS -#include // sigaction() -#include // printf(), fprintf(), stdout, stderr, perror(), _IOLBF -#include // memset() -#include // ITIMER_REAL, ITIMER_VIRTUAL, ITIMER_PROF, struct itimerval, setitimer() -#include // true, false -#include // INT_MAX -#include - -class Timer { - public: - int type_ = 0; - void (*handler_) (int) = nullptr; - int ms_ = 0; - bool oneShot_ = true; - class Types { - public: - enum { - ITIMER_REAL, - ITIMER_VIRTUAL, - ITIMER_PROF - }; - } Types; - int timer_signal(int timer_type); - void set_timer(int type, void (*handler) (int), int ms, bool oneShot); - static void timer_handler (int signum); -}; - -int Timer::timer_signal(int timer_type) { - int sig; - - switch (timer_type) { - case ITIMER_REAL: - sig = SIGALRM; - break; - case ITIMER_VIRTUAL: - sig = SIGVTALRM; - break; - case ITIMER_PROF: - sig = SIGPROF; - break; - default: - fprintf(stderr, "ERROR: unknown timer type %d!\n", timer_type); - exit(EXIT_FAILURE); - } - - return sig; -} - -void Timer::set_timer(int type, void (*handler)(int), int ms, bool oneShot) { - type_ = type; - handler_ = handler; - ms_ = ms; - oneShot_ = oneShot; - printf("oneshot: %s\n", oneShot ? "true" : "false"); - struct itimerval timer; - struct sigaction sa; - - /* Install signal handler for the timer. */ - memset (&sa, 0, sizeof (sa)); - sa.sa_handler = handler; - sigaction (timer_signal(type), &sa, NULL); - - /* Configure the timer to expire after ms msec... */ - // convert ms to seconds and ms - - int milliseconds = ms; - int seconds = milliseconds; - if (seconds > 999) { - seconds /= 1000; - milliseconds -= seconds * 1000; - } else seconds = 0; - printf("ms = %d\nmilliseconds = %d\nseconds = %d\n", ms, milliseconds, seconds); - - assert(seconds <= 60); - - timer.it_value.tv_sec = seconds; - timer.it_value.tv_usec = milliseconds; - - if (oneShot) { - timer.it_interval.tv_sec = 0; - timer.it_interval.tv_usec = 0; - } else { - timer.it_interval.tv_sec = seconds; - timer.it_interval.tv_usec = milliseconds; - } - if (setitimer (type, &timer, NULL) < 0) { - perror("Setting timer"); - exit(EXIT_FAILURE); - }; -} - -bool firstrun = false; - -Timer timer = Timer(); - -void Timer::timer_handler(int signum) { - static int count = 1; - if (!firstrun) { - fprintf (stderr, "> FIRST RUN timer ms = %d, count = %03d\n", timer.ms_, count++); - firstrun = true; - run(); - } else { - fprintf (stderr, "> YIELDING timer ms = %d, count = %03d\n", timer.ms_, count++); - yield(); - } -} - -int YIELD_THREAD(void * arg) { - // timer is per process, the process it is set in must exist in order to recieve a signal - timer.set_timer(timer.Types.ITIMER_REAL, Timer::timer_handler, 1000, false); - pause(); - return 0; -} - -int THREAD_CREATE(void * nu) { - Stack x = Stack(); - x.alloc(4096); - puts("THREAD_CREATE starting YIELD_THREAD"); - long int pid = clone(YIELD_THREAD, x.top, CLONE_VM|SIGCHLD, nullptr); - if (pid == -1) perror("THREAD_CREATE clone"); - // sleep for 1 second to allow for pause - sleep(1); - // a stack is not needed since the process pauses - x.free(); - return 0; -} - -int main(){ - /* Flush each printf() as it happens. */ - setvbuf(stdout, 0, _IOLBF, 0); - setvbuf(stderr, 0, _IOLBF, 0); - - start_thread(thr1); - start_thread(thr2); - Stack x = Stack(); - x.alloc(4096); - puts("starting THREAD_CREATE"); - long int pid = clone(THREAD_CREATE, x.top, CLONE_VM|SIGCHLD, nullptr); - if (pid == -1) { - perror("clone"); - x.free(); - return 0; - } - puts("waiting for THREAD_CREATE"); - if (waitid(P_PID, pid, nullptr, WEXITED) == -1) { - perror("waitid"); - x.free(); - return 0; - } - puts("waited for THREAD_CREATE"); - x.free(); - pause(); - return 0; -} \ No newline at end of file diff --git a/threads.h b/threads.h deleted file mode 100644 index 975577c..0000000 --- a/threads.h +++ /dev/null @@ -1,31 +0,0 @@ -/************************************************************* -* - Author: Denny Abraham Cheriyan, Adrin Peter Fernandes - Contains functions to Start, Run and Yield to other threads - -*/ - -#include "q.h" - -const int STACK_SIZE = 8192; -TCB_t *RunQ = 0; - -void start_thread(void (* function)(void)){ - void *stack = (void *) malloc (STACK_SIZE); - TCB_t *tcb = (TCB_t *) malloc (sizeof (TCB_t)); - init_TCB(tcb,function,stack,STACK_SIZE); - AddQ(&RunQ,tcb); -} - -void run(){ - ucontext_t parent; - getcontext(&parent); - swapcontext(&parent, &(RunQ->context)); -} - -void yield(){ - ucontext_t *current = &(RunQ->context); - RotateQ(&RunQ); - swapcontext(current,&(RunQ->context)); -} - From 6e98ea51fa0c91a446bf696b2aa03432b32ab517 Mon Sep 17 00:00:00 2001 From: brothercomplex Date: Sat, 2 Nov 2019 12:34:44 +1000 Subject: [PATCH 7/8] update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 4a5a9de..72a1a16 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ Routines that will allow a program to run, with multiple threads, using preempti * Ubuntu 14.04 * g++ compiler +* gnu make +* cmake ### To test threads library ### From 93431f955073264f4051f90ead5f51f0a2a1b4d2 Mon Sep 17 00:00:00 2001 From: brothercomplex Date: Sat, 2 Nov 2019 13:13:51 +1000 Subject: [PATCH 8/8] refactored scheduler --- libthread/tests/thread.cpp | 36 ++++++++++--------------- libtimer/include/internal/sched.h | 45 +++++++++++++++++++++++++++++++ libtimer/include/timer.h | 7 ++--- 3 files changed, 63 insertions(+), 25 deletions(-) create mode 100644 libtimer/include/internal/sched.h diff --git a/libthread/tests/thread.cpp b/libthread/tests/thread.cpp index 055cf33..798c882 100644 --- a/libthread/tests/thread.cpp +++ b/libthread/tests/thread.cpp @@ -6,10 +6,6 @@ */ #include -#include // sleep -#include // SIGCHLD -#include // clone -#include // wait #include // std::this_thread #include // std::chrono_literals @@ -40,6 +36,8 @@ bool firstrun = false; Timer timer = Timer(); +// declare a custom timer handler + void Timer::timer_handler(int signum) { static int count = 1; if (!firstrun) { @@ -52,11 +50,13 @@ void Timer::timer_handler(int signum) { } } -int YIELD_THREAD(void * arg) { - // timer is per process, the process it is set in must exist in order to recieve a signal - timer.set_timer(timer.Types.ITIMER_REAL, Timer::timer_handler, 1000, false); - pause(); - return 0; +// declare a custom schedule yeilder + +int Sched::yield(void * arg) { + // timer is per process, the process it is set in must exist in order to recieve a signal + timer.set_timer(timer.Types.ITIMER_REAL, Timer::timer_handler, 1000, false); + pause(); + return 0; } int main(){ @@ -64,21 +64,13 @@ int main(){ setvbuf(stdout, 0, _IOLBF, 0); setvbuf(stderr, 0, _IOLBF, 0); - start_thread(thr1); - start_thread(thr2); - - Stack x = Stack(); - x.alloc(4096); - // start in a new process to prevent its signal handler from being modified once set - long int pid = clone(YIELD_THREAD, x.top, CLONE_VM|SIGCHLD, nullptr); - if (pid == -1) perror("YIELD_THREAD clone"); - // sleep for 1 second to allow for pause - sleep(1); - // a stack is not needed since the process pauses - x.free(); + Sched foo = Sched(); // scoped initialization and de-initialization of the preemptive scheduler + + start_thread(thr1); + start_thread(thr2); + // let threads to do something for 8 seconds sleep(8); puts("exiting"); - kill(pid, SIGTERM); return 0; } diff --git a/libtimer/include/internal/sched.h b/libtimer/include/internal/sched.h new file mode 100644 index 0000000..ec80352 --- /dev/null +++ b/libtimer/include/internal/sched.h @@ -0,0 +1,45 @@ +// +// Created by brothercomplex on 2/11/19. +// + +#ifndef custom_threads_libtimer_sched +#define custom_threads_libtimer_sched + +#include +#include // sleep +#include // SIGCHLD +#include // clone +#include // wait + +class Sched { + long int pid; + public: + static int yield(void * arg); + Stack x = Stack(); + Sched() { + puts("starting Scheduler"); + x.alloc(4096); + // start in a new process to prevent its signal handler from being modified once set + pid = clone(yield, x.top, CLONE_VM|SIGCHLD, nullptr); + if (pid == -1) perror("YIELD_THREAD clone"); + puts("successfully started Scheduler"); + } + ~Sched() { + if (pid != -1) { + puts("stopping Scheduler"); + kill(pid, SIGTERM); + siginfo_t info; + if (waitid(P_PID, pid, &info, WEXITED | WSTOPPED) == -1) { + perror("waitid"); + puts("failed to stop Scheduler"); + return; + } + if (info.si_code == CLD_KILLED && info.si_status == SIGTERM) + puts("successfully stopped Scheduler"); + else puts("failed to stop Scheduler"); + x.free(); + } + } +}; + +#endif //custom_threads_libtimer_sched diff --git a/libtimer/include/timer.h b/libtimer/include/timer.h index 8f2d5f7..0701938 100644 --- a/libtimer/include/timer.h +++ b/libtimer/include/timer.h @@ -3,8 +3,7 @@ // #ifndef custom_threads_libtimer -#define FOREGROUND_SERVICE_TIMER_H - +#define custom_threads_libtimer #include // exit(), EXIT_FAILURE, EXIT_SUCCESS #include // sigaction() @@ -14,6 +13,8 @@ #include // true, false #include // INT_MAX +#include "internal/sched.h" + class Timer { public: int type_ = 0; @@ -33,4 +34,4 @@ class Timer { static void timer_handler (int signum); }; -#endif //FOREGROUND_SERVICE_TIMER_H +#endif //custom_threads_libtimer \ No newline at end of file