Author Topic: SBT  (Read 33342 times)

0 Members and 1 Guest are viewing this topic.

JRS

  • Guest
SBT
« on: September 19, 2014, 10:39:16 PM »
I'm working on a new Script BASIC extension module to run one or more instances of SB as an extension module function call. (sbt.so) The created instance uses libscriba.so which is the Script BASIC runtime in a shared object. Charles's DLLC for Windows already does this and more. This is primarily for Linux.

embed.sb
Code: [Select]
DECLARE SUB SB_New ALIAS "SB_New" LIB "sbt"

SB_New "test.sb", "JRS"

test.sb
Code: [Select]
cmd = COMMAND()

PRINT "ARG = ",cmd,"\n"

FOR x = 1 TO 5
PRINT x,"\n"
NEXT

Output


jrs@laptop:~/sb/sb22/sbt$ time scriba embed.sb
ARG = JRS
1
2
3
4
5

real   0m0.005s
user   0m0.004s
sys   0m0.004s
jrs@laptop:~/sb/sb22/sbt$


The resulting time is scriba loading and processing the embed.sb script which instantiates another SB object that runs test.sb8)

Threading support will be included as an optional run mode. (Load/Run, Load Only, Load/Run as thread)

JRS

  • Guest
Re: SBT
« Reply #1 on: September 20, 2014, 02:39:28 AM »
Here is the beginning of my proof of concept sbt.so extension module. (in C BASIC)

Code: C
  1. // Script BASIC Thread extension module
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7. #include <math.h>
  8. #include <time.h>
  9. #include "../../basext.h"
  10. #include "../../scriba.h"
  11. #include "cbasic.h"
  12.  
  13.  
  14. /****************************
  15.  Extension Module Functions
  16. ****************************/
  17.  
  18. besVERSION_NEGOTIATE
  19.   RETURN_FUNCTION((int)INTERFACE_VERSION);
  20. besEND
  21.  
  22. besSUB_START
  23.   DIM AS long PTR p;
  24.   besMODULEPOINTER = besALLOC(sizeof(long));
  25.   IF (besMODULEPOINTER EQ NULL) THEN_DO RETURN_FUNCTION(0);
  26.   p = (long PTR)besMODULEPOINTER;
  27.   RETURN_FUNCTION(0);
  28. besEND
  29.  
  30. besSUB_FINISH
  31.   DIM AS long PTR p;
  32.   p = (long PTR)besMODULEPOINTER;
  33.   IF (p EQ NULL) THEN_DO RETURN_FUNCTION(0);
  34.   RETURN_FUNCTION(0);
  35. besEND
  36.  
  37.  
  38. /*****************************
  39.  Create Script BASIC Instance
  40. *****************************/
  41.  
  42. besFUNCTION(SB_New)
  43.   DIM AS pSbProgram pProgram;
  44.   DIM AS char PTR sbfilename;
  45.   DIM AS char PTR sbcmdline;
  46.   besARGUMENTS("z[z]")
  47.     AT sbfilename, AT sbcmdline
  48.   besARGEND
  49.   pProgram = scriba_new(malloc,free);
  50.   scriba_SetFileName(pProgram, sbfilename);
  51.   scriba_LoadSourceProgram(pProgram);
  52.   scriba_Run(pProgram, sbcmdline);
  53.   scriba_destroy(pProgram);
  54.   besRETURNVALUE = NULL;
  55. besEND
  56.  

JRS

  • Guest
Re: SBT
« Reply #2 on: September 20, 2014, 09:39:19 AM »
Charles,

I'm creating a higher level wrapper to the SB embedding API with the sbt ext. module. I want to get the basic embedding functions working before enabling threads. Do see any issues with IUP's message pump having multiple instances if not being run in a thread? Any guidance or code you wish to contribute to this DLLC (like) for Linux effort as it unfolds would be much appreciated.

John

Charles Pegge

  • Guest
Re: SBT
« Reply #3 on: September 20, 2014, 12:38:52 PM »

Hi John,

You would only ever need one instance of IUP in one application. Preferably, only one thread from your SB extn should be calling IUP. But I am not a thread expert. If you could think of an app that uses IUP, something that needs to work in the background while IUP runs the GUI. ..

Mike Lobanovsky

  • Guest
Re: SBT
« Reply #4 on: September 20, 2014, 02:23:22 PM »
You would only ever need one instance of IUP in one application.

This ain't so, Charles. There are a hellofalot of graphics apps around that use dozens of worker threads with scheduled access to a common drawing canvas to draw arcs or ellipses in segments and sectors, or images, in tiles. For instance, think of JPEG images or fast ray tracers. IUP isn't just a windowing system but also a powerful drawing library AFAIK, similar to SDL.

JRS

  • Guest
Re: SBT
« Reply #5 on: September 20, 2014, 02:26:14 PM »
I got it working. (finally)

Code: Text
  1. // Script BASIC Thread extension module
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7. #include <math.h>
  8. #include <time.h>
  9. #include "../../basext.h"
  10. #include "../../scriba.h"
  11. #include "cbasic.h"
  12.  
  13.  
  14. /****************************
  15.  Extension Module Functions
  16. ****************************/
  17.  
  18. besVERSION_NEGOTIATE
  19.   RETURN_FUNCTION((int)INTERFACE_VERSION);
  20. besEND
  21.  
  22. besSUB_START
  23.   DIM AS long PTR p;
  24.   besMODULEPOINTER = besALLOC(sizeof(long));
  25.   IF (besMODULEPOINTER EQ NULL) THEN_DO RETURN_FUNCTION(0);
  26.   p = (long PTR)besMODULEPOINTER;
  27.   RETURN_FUNCTION(0);
  28. besEND
  29.  
  30. besSUB_FINISH
  31.   DIM AS long PTR p;
  32.   p = (long PTR)besMODULEPOINTER;
  33.   IF (p EQ NULL) THEN_DO RETURN_FUNCTION(0);
  34.   RETURN_FUNCTION(0);
  35. besEND
  36.  
  37.  
  38. /**********************
  39.  Script BASIC Instance
  40. **********************/
  41.  
  42. besFUNCTION(SB_New)
  43.   DIM AS pSbProgram pProgram;
  44.   pProgram = scriba_new(malloc,free);
  45.   besRETURN_LONG(pProgram);
  46. besEND
  47.  
  48. besFUNCTION(SB_Load)  
  49.   DIM AS int sbobj;
  50.   DIM AS char PTR sbfilename;  
  51.   DIM AS int rtnval;
  52.   besARGUMENTS("iz")
  53.     AT sbobj, AT sbfilename
  54.   besARGEND
  55.   rtnval = scriba_SetFileName(sbobj, sbfilename);
  56.   scriba_LoadSourceProgram(sbobj);
  57.   besRETURN_LONG(rtnval);
  58. besEND
  59.  
  60. besFUNCTION(SB_Run)  
  61.   DIM AS int sbobj;
  62.   DIM AS char PTR sbcmdline;
  63.   DIM AS int rtnval;
  64.   besARGUMENTS("iz")
  65.     AT sbobj, AT sbcmdline
  66.   besARGEND
  67.   rtnval = scriba_Run(sbobj, sbcmdline);
  68.   besRETURN_LONG(rtnval);
  69. besEND
  70.  
  71. besFUNCTION(SB_Destroy)
  72.   DIM AS int sbobj;
  73.   besARGUMENTS("i")
  74.     AT sbobj
  75.   besARGEND
  76.   scriba_destroy(sbobj);
  77.   RETURN_FUNCTION(0);
  78. besEND
  79.  

Code: Text
  1. DECLARE SUB SB_New ALIAS "SB_New" LIB "sbt"
  2. DECLARE SUB SB_Load ALIAS "SB_Load" LIB "sbt"
  3. DECLARE SUB SB_Run ALIAS "SB_Run" LIB "sbt"
  4. DECLARE SUB SB_Destroy ALIAS "SB_Destroy" LIB "sbt"
  5.  
  6. sb = SB_New()
  7. SB_Load sb, "test.sb"
  8. SB_Run sb, "JRS"
  9. SB_Destroy sb
  10.  

Output

jrs@laptop:~/sb/sb22/sbt$ time scriba embed.sb
ARG = JRS
1
2
3
4
5

real   0m0.006s
user   0m0.004s
sys    0m0.000s
jrs@laptop:~/sb/sb22/sbt$

« Last Edit: September 20, 2014, 04:38:48 PM by John »

Mike Lobanovsky

  • Guest
Re: SBT
« Reply #6 on: September 20, 2014, 02:40:51 PM »
Patience wears away stones. :)

JRS

  • Guest
Re: SBT
« Reply #7 on: September 20, 2014, 03:01:30 PM »
Quote
Patience wears away stones.

Questioning your own stupidity sometimes has merit.  ::)

Next up is passing strings as SB scripts. This will also act as an on-the-fly expression evaluator. I also plan on testing if the MT module works without have to set up webdata like in sbhttpd. The end goal is that any instance can access the functions and variables of any other instance. Each SB instance can independently load whatever ext. modules it wishes to use. If sbt in IMPORTed then it can use the embedding API to access any of the other instances as long as it has a handle to the SB program object. All theory at this point.  8)

« Last Edit: September 20, 2014, 03:11:40 PM by John »

Mike Lobanovsky

  • Guest
Re: SBT
« Reply #8 on: September 20, 2014, 03:34:54 PM »
The end goal is that any instance can access the functions and variables of any other instance.

IIRC it ain't possible. The worker threads can access either global memory (that's the top-level memory of main thread) or their own thread pools. Criss cross access ain't allowed.

JRS

  • Guest
Re: SBT
« Reply #9 on: September 20, 2014, 03:52:33 PM »
Quote
IIRC it ain't possible.

Yes it is. SB instances contain their own pSBData structure and use libscriba.so for the runtime. This already works in DLLC so I'm not breaking new ground here. I have sbhttpd as a working model if I exclude the HTTP / service parts of it.


Mike Lobanovsky

  • Guest
Re: SBT
« Reply #10 on: September 20, 2014, 05:04:05 PM »
Are you sure cross thread data interchange doesn't go through a process level (i.e. global memory) proxy -- for example, that very libscriba.so -- rather than directly as you say?

Then anyway, what you call instances might not be actual threads but rather separate processes, after all. I'm not familiar with DLLC though. Let's see what Charles has to say on the subject.
« Last Edit: September 21, 2014, 01:16:03 AM by Mike Lobanovsky »

JRS

  • Guest
Re: SBT
« Reply #11 on: September 20, 2014, 06:07:50 PM »
For this first phase, the SB instances will not be running in a thread but as static sub-processes that get run one at a time. They are just static memory structures when not being called. The MT extension module manages a share memory/variable space each process (threaded or not) can access and be seen by the other SB processes. You can't make embedding calls from the host if the process is running as a thread. MT is the only way to share memory space with threaded instances.

JRS

  • Guest
Re: SBT
« Reply #12 on: September 20, 2014, 06:41:22 PM »
It seems that the Script BASIC scriba_LoadProgramString() function requires the binary (tokenized ready to run) code as a string. :(  I would need to make a few other calls to create the binary program string. (phase II)

I've moved on to calling functions and get/set variables in the started instance from the host SB.

Charles Pegge

  • Guest
Re: SBT
« Reply #13 on: September 20, 2014, 08:42:13 PM »
Mike,

DLLC supports callbacks, by storing the callback messages in channels, which form a shared table, accessible to all SB progs. Using the channel system, a callback can optionally be relayed to an SB procedure - an interprative callback.

DLLC also enables SB programs to run in separate threads, in parallel with the main.

As I recall, it is necessary to use separate threads for the relayed callbacks, otherwise GPF!  SB does not like running more than one procedure at a time in the same thread.

In many instances it may be more practical to periodically monitor the channel table for callback messages, without resorting to threads and all their complications.

Mike Lobanovsky

  • Guest
Re: SBT
« Reply #14 on: September 21, 2014, 01:07:31 AM »
Hi Charles,

Thanks for clarifying the DLLC mechanics.

DLLC supports callbacks, by storing the callback messages in channels, which form a shared table, accessible to all SB progs.
That's exactly what I meant by the glabal memory proxy.

Quote
SB does not like running more than one procedure at a time in the same thread.
That might be indicative of yet some global(s) in the SB engine left out without thread safe access precautions. But then it's only easy to overlook some minute detail in such a complex mechanism as a variant-based interpreter.