MXPA96004437A - Dynamic switching of bibliot tasks - Google Patents

Dynamic switching of bibliot tasks

Info

Publication number
MXPA96004437A
MXPA96004437A MXPA/A/1996/004437A MX9604437A MXPA96004437A MX PA96004437 A MXPA96004437 A MX PA96004437A MX 9604437 A MX9604437 A MX 9604437A MX PA96004437 A MXPA96004437 A MX PA96004437A
Authority
MX
Mexico
Prior art keywords
task
tse
dll
segment
routine
Prior art date
Application number
MXPA/A/1996/004437A
Other languages
Spanish (es)
Other versions
MX9604437A (en
Inventor
B Grigsby Kenneth
L Smundak Aleksander
Original Assignee
Informix Software Inc
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Priority claimed from US08/537,235 external-priority patent/US5802368A/en
Application filed by Informix Software Inc filed Critical Informix Software Inc
Publication of MX9604437A publication Critical patent/MX9604437A/en
Publication of MXPA96004437A publication Critical patent/MXPA96004437A/en

Links

Abstract

The present invention relates to a method for providing a data memory per case in a particular dynamic link library, loaded in a random access memory address space, both as part of a first task and as part of a second task , loaded in the address space simultaneously, on a computer that has a memory management hardware, which includes a local descriptor table for mapping the selectors to addresses

Description

DYNAMIC SWITCHING OF LIBRARY TASKS BACKGROUND TO THE INVENTION Field of the Invention The invention relates to methods and programs for executing multiple instances of shared programs and libraries (file sets), under a multi-task operation system (applications) and, in particular, to the execution of such programs and libraries under an operation system, such as Microsoft Windows 3.1. Background A dynamic link library ("DLL") provides a shared library of keys and data that can be linked to multiple tasks (such as application programs) by an operating system, such as Microsoft® Windows 3.1 or Windows 3.11. In this context, it is convenient to be able to execute multiple cases of a DLL, and multiple cases of an application, simultaneously. The execution of multiple cases of an application in Windows 3.1 will require that the DLLs of the application be shared between cases of the application and through applications that use the same DLL. While this feature is available in a number of operating system environments, such as in Microsoft® Windows 95, it conflicts with the design of the Windows 3.1 DLLs and 3.11.
(From this point of view, the term DLL will refer to DLLs as is known in the Windows 3.1 and 3.11 environment, which run on icroprocessors compatible with the 80x86 family of the Intel® microprocessor-brand trademark, and the Windows term will refer to Windows 3.1 and 3.11 environments, unless expressly mentioned otherwise.) In a Windows 3.1 DLL with multiple data segments, the global variables will be shared by all applications that use this DLL. In an operating system that is designed to run applications in separate address spaces, the memory must be allocated for each application and the application memory will be connected and disconnected by the operating system, changing a set of registers or memory locations. to connect to the appropriate memory for the application. The Windows 3.1 environment was not designed in this way, although Intel microprocessors make the functionality available in the mode of operation called protected mode. Intel's protected mode has the same segment recorders (CS, DS, ES and SS) as the real mode, but the segment address is a 16-bit element known as a "selector". Protected mode requires a block of memory known as a "descriptor table". This descriptor table can contain up to 8,192 8-byte entries. The upper 13 bis of the selector is a displacement that refers to one of these inputs. The entry of the descriptor table contains a "base address" that determines the starting point for the memory to which the selector has access and a "limit address" that supplies the end of the memory range accessible by the selector. In other multi-task operating systems, the GDT (global descriptor table) provided by the protected mode of Intel, is used to manage the memory of the operating system and each process obtains its own LDT (local descriptor table) for its own memory. In this way, the processes are protected from mutual interference. However, Windows 3.1 uses a single LDT, which is shared between the operating environment and all Windows applications.
Referring to Figure 1, and as noted above, the global variables in segments 16, 17 and 18 will be shared by all applications 10, 11 and 12, using each DLL 13, 14 and 15 of Windows 3.1. (In the figure, the applications are APP1, APP2 and a second case of APP2, respectively, and the DLLs are DLLl, DLL2 and DLL3, respectively.) This is a side effect of the fact that the key in a DLL is the same, regardless of which application is in access to it. A DLL is initialized once it is first loaded into memory by a loader program. If a DLL has more than one data segment, a selector for each data segment is assigned by the loader and inserted into the key segment at any point in the key with access to the data segment. Since this selector address is inserted into the key segment, which is shared between applications, the data must also be shared. This results in global data shared between applications.
Several approaches to dealing with this problem have been carried out. All require the same method to collect case data by application in a memory block allocated by the application and maintain the "base address pointer" of this memory block for use when the application starts running.
In a first approach, the task (application) passes the base pointer as a parameter in each call to the DLL. One drawback of this approach is that it is not applicable in a situation where the DLL is the realization of a C ++ class library and some of the classes have shared variables.
In a second approach, the base pointer is kept in a well-known place in the task, for example, in a fixed direction at the beginning of the stack segment. The appropriate pointer of the base is made available automatically when each task comes in, because each task has a unique address of the stack. One drawback of this approach is that it requires a special structure and a fixed position for each DLL used. COMPENDIUM OF THE INVENTION The invention provides data memories per case in a DLL linked to multiple tasks or multiple cases of a task. A base address for each case of the DLL is to keep individual DLLs and the base addresses are connected when the tasks are also connected. The operating system is required to inform an external service or DLL of the 'switch', named TSE (Task Switching Intensifier), when the tasks are switched, so the base addresses can be connected and other domestic services can be done. The collection of data per case in a block of memory for each application is done by a mechanism that involves both the compiler and the linker. In the context of an illustrative language of the fourth generation (which we named "FGL") that generates the key C for further compilation by a compiler C, the C language key, which will be described, is done by the FGL compiler; otherwise, it is done by a programmer who writes the key C, and the invention can be practiced in any way. (The term C will be used generically to also encompass C ++, as is done, for example, in Microsoft® Visual C ++ compiler, version 1.5.) By inserting instructions to the linker in a C program to indicate the segment to which a variable belongs, the Linker will be assigned to all the variables belonging to the segment in a block. By including further instructions to the linker in the supplied binding key in a bound object of the assembler, it creates a unique segment group to prevent the linker from mixing these segments with others. Therefore, when the DLL is loaded, this segment will have its own descriptor, which is mapped at a runtime to a specific physical address of the case. The invention has a number of advantages. For example, using the invention, only variable declarations need to be modified to achieve the operation per case and the efficient results of the key.
Other advantages and features will become apparent from the following description and from the claims. BRIEF DESCRIPTION OF THE DRAWINGS The accompanying drawings, which are incorporated in, and constitute part of, the specification, schematically illustrate specific embodiments of the invention and, together with the general description given above and the following detailed description of the modalities, will serve to explain the principles of the invention. invention.
Figure 1 is a block diagram illustrating the tasks (applications), DLLs and data segments of the DLL in the relationship of the prior art. Figure 2 is a block diagram illustrating a relationship created by a task switching intensifier (TSE). Figure 2A is a schematic diagram of tables illustrating the relationship of a selector of the DLL to an address of the descriptor base of the local descriptor table (LDT), to the data segments created by the TSE. Figure 3 is a flow chart illustrating the process associated with carrying a DLL in memory. Figure 4 is a flow diagram illustrating the process associated with the first start of a task.
Figure 5 is a flow chart illustrating the process associated with switching a task.
DETAILED DESCRIPTION Referring to Figure 2, applications 100, 110 and 120, are linked, as shown, to the three DLLs 130, 140 and 150. Applications 110 and 120 are two instances of the same program. This corresponds to Figure 1, except for the improvements made to the DLL applications for TSEs, which will be described. However, with the improvements, a DLL, such as DLL2 140, will have a separate data segment 170, 171 and 172 for each task case that uses the DLL, that is, in this illustration, applications 100, 110 and 120 Returning to Figure 2A, the TSE effects the switching between the data segments, illustratively the segments 171 and 172, by switching the contents of the base address portion 220 of the descriptor 10 in the LDT 200) to which one or more are pointing. selectors 142 (in DLL DLL2 140). Base address 220 will point to the original data segment 175 loaded with DLL2 140, when no application is using DLL2 140 and data segment 172 when application 120 is using DLL2 140. Thus, returning again to Figure 2, the TSE will cause the contents of the base address to point to the data segments, as shown in Figure 2: DLLl 130 will point to data segment 160 when APP1 100 is bound to DLLl; DLL2 149 will point to data segment 170 when APP1 100 is bound to DLL2; DLL2 140 will point to data segment 171 when APP2 (first case) 110 is bound to DLL2; DLL2 will point to data segment 172 when APP2 (second case) 120 is bound to DLL2; DLL3 150 will point to data segment 180 when APP2 (first case) 110 is bound to DLL3; and DLL3 150 will point to data segment 181 when APP2 (second case) 120 is bound to DLL3.
Registry. Returning to Figure 3, when a DLL is carried in memory, it registers itself with TSE, step 340, providing an automatic call notification function. When a DLL is loaded calling the TSE routines, this TSE is also loaded, if it is not already loaded, step 310. After all the required modules have been loaded, (step 320), Windows calls LibMain () for a DLL (step 330), which calls the TSE to register all the DLLs linked to the task (steps 340 and 350).
Returning now to Figure 4, when the execution of a task begins, it calls WinMain (), which calls the TSE to register the task with the TSE, steps 410 and 420. WinMain () also calls TSE to look through from the list of DLLs of the task and to make the automatic calls of notifications of the DLLs, registered with them, steps 430, 440 and 445. The automatic call function will typically require that the TSE exemplify some segments, steps 450, 452 and 454, and then calls the module initialization functions to initialize the global and class member variables, step 460. Because the exemplification (described below) copies the original segment, all static initializations generated by the global variables will be preserved. .
Concrete Exemplification of the Segment. To exemplify a segment (which may belong to an application or to the DLL), the TSE makes a copy of a segment memory and remembers its flat direction. After that, each time a task is activated, the TSE will adjust the address in the corresponding entry of the local descriptor table (LDT) to point to the remembered address. Thus, each case of the task will use the case data.
Initialization. To provide data per case to multiple tasks that share a DLL, the data from the separate modules that comprise a DLL are consolidated to allow easy duplication for each case of an application, using the DLL. This is done by including pragmatic facts of the C compiler in the source key to name the segments and groups of segments. Likewise, an assembly language object is created to be linked to the DLL to consolidate groups of segments, so the linker will group together data segments, according to the names provided in the pragmatic facts of the compiler. The assembler object also provides a function that returns the base address of this data segment. An establishment of the initialization functions is provided, which includes LibMain (). (A LibMain () must be provided to initialize all Windows DLLs). This TSE LibMain () calls the TseDllRegister () to register the DLL with the TSE, step 340. Its arguments are (1) the "case manipulation" of Windows to identify the DLL and (2) the address of a call function automatic, which will be called by the TSE every time the DLL needs initialization for a new exemplification. The call to TseDllRegister () causes the TSE to insert the DLL into a list of registered DLLs. An establishment of the initialization functions is provided to be called from the start-up module, for example, the WinMainQ function, of an application for registration with the TSE. These include TseTaskRegister (), which causes the TSE to place the Windows task handling in a list of tasks registered with the TSE, stage 420, and TseDLLInstantiateALL (), which causes the TSE to search through the table of modules to call the task and compare the list of DLLs used by the task to the list of registered DLLs. When the TSE finds a correspondence, it calls the automatic call function, previously registered for the DLLs, when it is called TseDllRegister (), step 445. In response, the DLL that the TSE is calling passes back to the selector, which references the segment of data per case of the DLL. The TSE allocates a block of memory (belonging to the task to be used by the memory, not the TSE DLL) of the same size as the original data segment referenced by the selector and copies the contents of the original data segment into the newly assigned memory block, step 452. The TSE keeps the original selector and newly assigned block selector in a list of selector pairs for each DLL used by the task, step 454. (Instead of TseDLLInstantiateALL (), TseDLLInstantiate () can be called as often as necessary to specifically exemplify particular DLLs.) In addition, the TSE also invokes the automatic call function and directs it to call any module initialization function, step 460. The module initiation-lysis functions are typically generated by compilers for the performance of functions, such as the variables of register classes and global initialization.
In order to modify the task switching events, the TSE calls the NotifyRegister () function of Windows Tools Help API and the address of a TSE function (the "automatic notification call") that will be called by Windows at any time that any task enters or leaves, steps 472 and 474. The TSE must pass NotifyRegister () a task manipulation as a parameter, and uses this task manipulation of the first task that the TSE called. NotifyRegister () associates the automatic notification call with this task manipulation. When this task is completed, the TSE recognizes the condition and, as will be described later, associates it with another task registered in the TSE. This particular task is named as the task of the TSE. Operation. Returning to Figure 5, when a task comes in, the automatic notification call in the TSE checks the list of tasks registered with the TSE to see if the input task is registered, steps 510 and 530. If so, and exit, the stage 540, the TSE switches the descriptors of the selector pairs;, so that the original selector references the memory block allocated for the task by the TSE, step 532, and the assigned selector references the original memory segment. When a task ends or exits, the automatic call in the TSE checks the list of tasks registered with the TSE to see if the task is registered, step 510. If this is the case, the TSE connects to the descriptors of the selector pairs of so that the original selector refers to the original data segment and the selector assigned by TSE refers to the assigned memory block, step 542. In this way, the TSE restores the mapping to which Windows thinks it is. If it is recorded and terminated, step 520, the TSE removes the memory allocation per assigned, associated case, step 522, deletes the record of the task, step 524 and, if the task is one associated with receipt of the notifications of the task switch of the TSE, this TSE transfers the association to another task registered in TSE, step 526.
The TSE connects the base addresses using the DOS Protected Mode Interface (DPMI) functionality. This TSE uses two functions provided by the DPMI, one to request the base address of a descriptor, directed by a selector provided by the application, and the other to change the base address of a descriptor, directed by a selector provided by the application. The task of the TSE, which is typical of the original task management that TSE uses when calling the NotifyRegister (), may end. In this case, the TSE calls NotifyUnregister () for the task management and then calls NotifyRegister () again, passing the task management of the first task in the list of tasks registered with TSE, whose first task will become the task of the TSE. This is done because Windows does not invoke the automatic call, if it is associated with a task that has ended.
Note that, in Windows, a block of memory can be its own or by an application or by a DLL. The data segments assigned by the loader as part of the loading of a DLL are owned by the DLL. The TSE of segments assigned to the data per case are specific to the task to which the TSE is linked, at the time that the TSE makes the assignment. If all tasks recorded with TSE are completed, this TSE will release the allocated memory and selectors and then it will finish.
Deletion of the Registry. Although the task of deleting the record is not strictly required, because TSE monitors the task completions and can be done automatically, it is provided by means of TseTaskUnregister (), as a safety precaution. A DLL that is to be used with the TSE must be encoded to delete the registry by itself, in its WEP () procedure (Windows Exit Procedure), for example. TSE API details. The following five routines provide library exemplification services. 1. BOOL TseDllRegister (hLiblnst, initCallback) registers the DLL identified by hLiblnst with TSE. The second argument is the address of the automatic call function, invoked by TSE when the DLL is exemplified / terminated. TseDllRegister () is usually called LibMain (), where case management is available. Thus, case management becomes a module management to simplify the query of the module table afterwards. 2. initCallback (wReason) is a place retention for the user function that is called by TSE. The wReason parameter specifies the case that the call is activated. When it is called because the DLL is specifically exemplified, the automatic call must exemplify all the segments that contain the data per case and then start them. 3. TseDllUnregister (hLib? Nst) removes the DLL identified by hLiblnst from the list of registered DLLs. 4. TseDllInstantiate (hLib? Nst) specifically exemplifies the DLL specified by hLiblnst for the current task. This routine checks that the DLL identified by hLiblnst is registered and ignores those that are not registered. Check that the current task is registered with the TSE. If the DLL has already been instantiated for the task, this routine returns. Otherwise, it invokes the automatic notification call of the DLL and stores the data information per case in the task list for this task.
. TseDllInstantiateAll (), calls TseDllInstantiate () for each DLL used by the current task.
The following three routines provide the services of the specific instantiation of the segment. 1. TSETASKRegister () adds the current task to the task list of the TSE. On the first call, it links the current task to the TSE (which is a DLL). (This task can be referred to as the task of the TSE.) This routine must be called before TseDllInstantiateQ or TseDllInstantiateAll (). 2. TseTaskUnregister () removes the current task from the TSE list. All the exemplified segments of the task are restored to their original state. 3. TseSegmentInstantiate (hInstance, hSeg ent) checks that the current task is registered. Assign a new segment, make a copy of hSegment in it and transfer the addresses of those two segments. The hlnstance argument identifies the owner of the segment: it is a handling of the DLL.
Data structures. The basic data structures of the TSE are a list of registered TSE libraries (a linked list of LIBENTRY structures) and a list of registered TSE tasks (a linked list of TSENTRY structures).
The list of registered libraries maintains the handling of modules of each DLL in the LIBENTRY structure as the primary search key, although the name of the module is also maintained for the purpose of inspecting errors. The initialization function indicator TSE_NOTIFYCB is kept here; it is a specific DLL and will not vary as a function of the application. The original DLL FGL_INSTDATA selectors (the selectors for the original data segment of the DLL) are also maintained for error detection and inspection purposes. The structures of the registered list of libraries are illustrated in the following table.
// Start of structure of Library Selector List structure tagLIBSEL. { structure tagLIBSEL * pNext; UINT selector; } structure typedef tagLIBSEL LIBSEL, * PLIBSEL; tagLIBENTRY structure. { c ar modName [9]; HMODULE hLibrary; CINITPROC plnitProc; // Call when Exe has been initialized // if "modulelnitialized is FALSE BOOL modulelnitialized; // TRUE if DLL has initialized UINT usageCount; // TSE usageCount (It may not be the same as the account used by the system // Inc / Dec when Start / finish the Task PLIEBSEL pSelüst; structure tagLIBENTRY * pNextLib; }; typedef structure of tagLIBENTRY LIBENTRY, * PLIBENTRY; The list of registered tasks of the TSE is a linked list of TSENTRY structures containing HTASK (task management) as the primary search key. It has an indicator to the linked list of the TLIBENTRY structures that identify the DLLs that are used by the task. This list is maintained for error detection and recovery. It also contains the linked list of TLIBSEL structures, where the original and assigned selectors are maintained to commute the input and output of the task. A "selSwitchMode" flag in the TLIBSEL structure determines whether the selector that is currently being used is the original selector or the selector assigned in this case. This is used for error detection and to change the selectors back to their original state, during the completion of the task. The name of the module and the handling of the module remain redundantly in TLIBENTRY and the TLIBSEL to inspect and detect errors. These data structures are illustrated in the following table. tagTLIBENTRY structure. { char modName [9]; // Name of DLL HMODULE Hübrary; // For DLL CINITPROC plnitProc; // Call when the Exe has been initialized // If "modulelnitialized is FALSE BOOL memoryAllocated; TRUE if the memory of DLL has been assigned BOOL modulelnitialized; TRUE if DLL is initialized PLIBSEL pSelList; // Linked list of selectors maintained by the structure of TSE tagTLIBENTRY * pNextLib;.};; Typedef struct tagTLIBENTRY TLIBENTRY, * PTLIBENTRY; structure tagTLIBSEL. { char modName [9]; // Name of the DLL that uses these selectors HMODULE hübrary; // HMODULE for the DLLs that use these selectors BOOL selSwitchMode; // SWITCHED = TRUE BOOL memoryAllocated; // True if it is the Assigned Memory UINT origSelector; // Original Selector UINT taskSelector; // Case Selector structure tagTLIBSEL * pNextSel; }; typedef struct tagTLIBSEL TLIBSEL, * PTLIBSEL; tagTSENTRY. { HTASK hTask; // Task HANDLE for task using structure HINSTANCE hlnstance; UINT instanceNumber; chartaskName [9]; char newTaskName [9]; char taskFilename [13]; char newTaskFilename [13]; BOOL dllslnitialized; // the Task has all the DLLs initialized PTLIBENTRY pTaskLibList; // Linked list of DLLs that use TSE for task PTLIBSEL pTaskSelList; // List of selectors used by TSE for task structure tagTSENTRY "nextTask;.}.; typedefstructtagTSENTRY TSENTRY, * PTSENTRY; Example of Sequencing and Application Initialization. The following discussion illustrates the initialization sequence for a MYAPP application that uses an MYLIB.DLL (it is assumed for illustration that it is a C library). [MYAPP] The user starts MYAPP.EXE. Kernel passes the control to astart (), which calls InitTask (), which is a kernel call to the load DLLs.
[KERNEL] For each DLL required by the application that is not already in memory, long kernel and calls its entry point libentry (). [MYLIB] The routine libentry () calls _cinit () for the initialization of the execution time of C, which in turn calls LibMain (). LibMain () registers the DLL with TSE, calling TseDllRegister (hLib, Initlnstance). [TSE] TSE adds (hLib, Initlnstance) to its registered list of libraries and returns to MYLIB [MYLIB] LibMainQ returns to TRUE (TRUE). [KERNEL] Kernel proceeds as before with the other DLLs. After all the DLLs have been loaded, the kernel returns to the application. [MYAPP] The application calls cinit () for the initialization of the execution time of C which it then calls WinMain (), where the user's key starts. WinMain () calls TSETASKRegister ().
[TSE] TSETASKRegister () adds the current task to the registered list of tasks. (No exemplified segment has been created yet.) [MYAPP] WinMain () calls TseDllInstantiateAll (). [TSE] TllinstantiateAll () explores the list of required DLLs by MYAPP. For each registered DLL, it invokes the automatic DLL call with a reason key that indicates which segments are to be exemplified. [MYLIB] The automatic call routine invokes TseSegmentlnstantiate. [TSE] TseSegmentlnstantiateO makes a copy of the segment, and adds original and copied selectors to the list of segments to be transferred in the activation of the current task. [MYLIB] After Tsesegmentlnstantiate () returns, the automatic call routine returns to TSE. [TSE] Continue for other DLLs.
[MYAPP] Executes the initialization key of the application system to the variables of registrar classes and initialization. Finally, call the main application module.
Consolidation and Initialization Data. As already mentioned, the data per case are linked in contiguous segments for the process by TSE. A data consolidation mechanism may also be necessary in the case of programming languages or environments with an object or class-oriented design, such as 4GL. can arise in two cases. First, for initialization, each compiled module can contain the key to be executed before the control obtains the main program. The classes that the application will use may have to be registered in order to calculate the variable displacements of members and the sizes of objects. Likewise, if any variable of a global and / or shared member is defined in a module and is explicitly initialized, the initialization key has to be executed. A 4GL compiler typically generates an initialization function per module and a variable that contains the address of the module. By having the linker form an array of these addresses, the boot key is able to call them easily.
Consolidation through the modules is also useful if a DLL is to be used by a pseudo-key interpreter, for which the DLL must provide function names and their addresses. An FGL compiler can generate an array of them for each module, and the linker can be made to consolidate these fixes of all the modules that the DLL contains. The Microsoft linker provides a consolidation mechanism in the form of logical segments (not to be confused with 80x86 memory segments, which are named segment groups). The logical segments control how the linker combines the key and data when it forms an executable of separate modules. Each object key entity (function key and global variable) belongs to a particular logical segment. A logical segment has a number of attributes associated with it, which control where it is going to be placed in the executable, which includes the group of segments and the class of segments. The group of segments is used by the linker to combine logical segments into physical segments: all the logical segments belonging to the same group are placed in a physical segment. To specify a group of logical segments, a directive GROUP is used in the assembly module. The segment class together with the segment name controls how the logical segments of different object modules are combined. The linker combines the data of all segments with the same name and class in a block of contiguous memory. Within the class, data belonging to the same segment is placed in a conti-guo block. The relative order of the segments within a class is determined by the order in which the linker sees them. With the Microsoft C compiler, variables can be assigned to specific segments with a #prgama directive. The manager #pragma data_seg ("MYSEGM, -MYCLASS") instructs the compiler to place the variables that follow the directive in the MYSEG segment, which belongs to the MYCLASS class. for multiple managers #pragma data_seg, the compiler generates logical segments in the reverse order of their declarations in the source key.
Thus, the data of separate modules can be consolidated in a contiguous array and their start and end address can be obtained as follows. First, each module must define the same logical sequence of segments, such as: #pragma data_seg ("FGL_FOO_END", "FGL_FOO") #pragma data_seg ("FGL_FOO_USER, FGL_FOO") #pragma data_seg ("FGL_FOO_BEGIN", "FGL_FOO") #pragma data_seg () Each object module will then contain the segments FGL_FOO_BEGIN, FGL_FOO_USER , and FGL_FOO_END, in that order. The data to be consolidated is then placed in segment FGL_FOO_USER, the middle segment in the group of the three.
The runtime start module declares the sequence of segments as before and supplies an inoperative element at startup: static footype _based (_segname ("FGL_FOO_BEGINH)) foo_begin = NULL (NULL); and the label at the end: static footype _based (_segname ("FGL_FOO_END")) foo_end = NULL (NULL). As a result, the executable will contain an array of data, of any kind, sandwiched between foo_begin and foo_end. Thus, if the data is an array of the initialization functions, this initialization can be achieved by calling only one routine and passing it to the vector address of the initialization functions and the address of the first word after its completion.
The consolidation of data and functions is useful, as mentioned, in the context of 4GL programs interpreted by a pseudo-key interpreter (p-key). The DLLs that support the data per case of the TSE can be made accessible to the interpreted applications of the p-key.
As described, each DLL will be formed to export a "userfunc" array, that is, an array of names of its functions and its entry points, for use by the interpreter to resolve the references to the functions of the DLL, same as for the debugger.
In addition to function names, the userfunc array can also contain name / address pairs of global and shared member variables, defined in a DLL, that need to be accessed from the p-key interpreter or from a debugger .
Generation of userfunc. A 4GL compiler can generate a userfunc array for each FGL module. It contains the entries for all the functions and methods defined in the module as follows: // Provide ordering of segments #pragma data_seg ("FGL_UF_END", "FGL_UF") #pragma data_seg ("FGL_UF_USER", "FGLJJF") #pragma data_seg ( "FGL_UF_BEGIN", "FGLJJF") // Reset to the implicit data segment #pragma data_segO // Put userfunc in the segment FGL_UF_USER static struct userfunc _bases (_segname ("FGL_UF_USER")) FGLuserfuncQ =. { ffunctionl ", (USERFUNC) functionl, < #args >.}. ffunction2", (USERFUNC) function2, < #args > } }; The runtime start can then supply the entry point for the consolidated userfunc array as follows: // Provide inoperable exportable input struct userfunc_bases (_segname ("FGL_UF_BEGIN") _export _FGLuserfuncQ = { . { "" NULL} // thus it will not correspond to any name}; // A sentinel static struct userfunc _bases (_segname ("FGL_UF-END") _FGLuserfunc [] = { { NULL, NULL.}.}.; Generate Module Initialization Key A 4GL compiler can generate the module initialization function in a FGL_INIT segment, as follows: // Define ordering the segment, then readjust to the implicit segment #pragma data-seg ("FGL_INIT_END", "FGLJNIT") #pragma data-seg ("FGL_INIT_USER", " FGLJNIT ") #pragma data-seg (" FGLJNIT_BEGIN "," FGLJNIT ") #pragma data-segO Define address of the static void module initialization function "* bases (_segname (" FGLJNITJJSER ")) _FGLinitptr = (void *) _ FGLinitc; The runtime start can provide an entry point for the fixation of the initialization functions of the consolidation module as follows: // Supply the start void * bases Csegname ("FGLJNITJ3EGIN")) FGLinitfuncO = NULL; // Supply sentinel void * bases (_segname ("FGLJNIT_END")) FGLinitfuncN = NULL; As a result, & _FGLinitfuncO and & FGLinitfuncN are start and end addresses, and if the FGL_INIT_USER segment is loaded with the addresses of the initialization routine, this initialization can be performed by calling a routine, for example, fglInitAll (& _FGLinitfuncO , & _FGLinitfuncN), which calls successively each function whose address is loaded in the segment.
Segments and Logical Groups. In order to save space in the implicit data segment of the executable in the data segment exemplified in a DLL, all static data can be placed in a separate group of read-only segments, ie, for example, FGL_RODATA. This group may contain illustrative segments listed in the module of the set language source key, indicated later in this description. For an application, the segments in FGL_RODATA and its own group are defined in an assembler object key module. In addition to the definitions of segments and groups, the module contains a inoperative variable with reference in the initialization module of the request, to ensure that this module of the assembler object is loaded with the request to give effect to the segment and group definitions in the linker.
For a DLL there can be two specific groups of 4GL, FGL_RODATA co or described and FGL_INSTDATA. FGL_INSTDATA can contain the logical segment for the information and variable data per case. The definitions of segments and groups for a DLL are in an assembly language module that also contains the FGLInstanceSeg () function, which returns the selector assigned to the FGL_INSTDATA group. The source key for such a set module is shown in the following table.
This module contains definitions of the logical segments and segment groups (that is, the physical segments) used by the system and the user's FGL DLLs. It also contains the FGLInstanceSegO function that returns the segment of the FGLJNSTDATA. The following table summarizes the defined segments, their order and their use.
* Seament Class Size Rd ?? ri Use Provides the address of the 'FGLJNITJ3EGIN FGLJNIT 4 RO array of module initialization functions Function addresses 'FGLJNITJJSER FGLJNIT Varies the initialization RO of the Sentinel module for the array 'FGLJNITJ? ND FGLJNIT 4 RO Provides the address on FGL_UF_BEGIN FGLJNIT 12 RO fix userfunc 'FGL_UF_USER Fix Userfunc FGLJNIT Varies RO Sentinel of array' FGLJJFJ? ND FGLJNIT 12 RO Userfunc Virtual address table of 'FGL_VT FGL_VT Varies RO class Another kind of information 'FGL_CI FGL_CI Varia RW User data 'FGL_DATA FGL_DATA Varies RW; Two groups of segments are defined:; FGL_RODATA contains read-only data (FGLJNIT ooc, segments FGL_UF_xxx, and FGL_VT); FGL INSTDATA contains exemplified data (FGL_DATA and FGL_CI) Related segments Init. FGL_UNIT_BEGIN SEGMENT PUBLISHED WORD 'FGL INIT' FGLJNITJ3EGIN ENDS FGLJNITJJSER SEGMENT PUBLISHED WORD 'FGL INIT' FGLJNITJJSER ENDS FGLJNIT J = ND SEGMENT PUBLIC WORD 'FGL INIT' FGLJNITJ? ND ENDS FGLJ ODATA GROUP FGLJNITJ3EGIN, FGLJNITJJSER, FGLJNITJ = ND; segments related to Userfunc FGL_UF_BEGIN SEGMENT PUBLIC WORD 'FGLJJF' FGLJJFJ3EGIN ENDS FGL_UF_USER SEGMENT PUBLISHED WORD 'FGL UF FGLJJFJJSER ENDS FGL_UF_END SEGMENT PUBLIC WORD 'FGL UF' FGL_UF_END ENDS FGL_RODATA GROUP FGL_UF_BEGIN, FGLJJFJJSER, FGLJJFJ? ND; VTAB FGL_VT SEGMENT PUBLIC WORD 'FGL VT' FGL VT ENDS FGL_RODATA GROUP FGL_VT; CLASSINFO FGL_CI SEGMENT PUBLIC WORD 'FGL: _CI' FGL_CI ENDS FGLJNSDATA GROUP FGL_CI; User Data FGLJDATA SEGMENT PUBLIC WORD 'FGL_DATA dataLabel Label byte FGL_DATA ENDS FGLJNSDATA GROUP FGL_DATA ; FUNCTION: FGLInstanceSeg: PURPOSE to return the group segment FGLJNSTDATA .MODELO GRANDE, C .CLAVE FGLInstanceSeg PROC MOV AX, SEG datalabel RETF J = GLInstanceSeg ENDP PUBLIC _FGLInstanceSeg END FINAL Multiple Cases of Programs .EXE. As a corollary of the ability to execute multiple exemplifications of a DLL simultaneously, it is convenient to be able to execute multiple exemplifications of a program simultaneously and, more particularly, multiple exemplifications of an .EXE program. Windows limits one's ability to execute multiple exemplifications of an .EXE program by rejecting requests to execute multiple instances of an .EXE program that has multiple segments that can be written, which limit the data that can be written to the .EXE programs that are written. they try for multiple exemplifications at 64 Kbytes (16 bis address space). When multiple instances of an .EXE program are executed, the key can be shared by all cases and the data that can be written per case, being limited to 64 kBytes, for each case that has its own value of the DS task specific logger , for Windows. To overcome the limitation of Windows, the segments that can be written in an .EXE program can be disguised, so Windows will load the multiple cases and share a copy of the key; and then the techniques described above, of dynamically creating segments that can be written by case and transferring the base addresses in the LDT, can be applied to achieve a greater amount of data that can be written in an .EXE program. However, a simpler solution is available. The TSE achieves the desired result by transforming the name of an .EXE program that has invoked TSE (presumably because it tries to be executed in multiple cases) in the Windows module table. The test by which Windows recognizes that a second case of a program is executed, is again the case sensitive, while the stored name is always the higher case. By changing, for example, the case of the first letter of the .EXE program name in the module table, multiple cases can be executed. This is done at the expense of some computer memory, however, since each case will not only have its own copy of the data that can be written, as desired, but also its own copy of the program key.
The present invention has been described in terms of the specific embodiments. However, the invention is not limited to these specific modalities. Rather, the scope of the invention is defined by the following claims and other embodiments are within the scope of the claims. For example, the invention can be used by other languages, such as PASCAL, to support data of multiple cases. Similarly, the invention can be used to carry out detailed support on top of an operating system that would not otherwise be provided. Likewise, what has been described is a modality in which the data per case is loaded in one or more segments per case and shared data will be loaded in other segments (in particular DGROUP). in the mode of a small memory model or having a DGROUP per case, the base address of the descriptor by the DGROUP is also switched by the TSE.

Claims (5)

  1. NOVELTY OF THE INVENTION Having described the present invention, it is considered as a novelty and, therefore, the content of the following is claimed as property: CLAIMS 1. A method for supplying a data memory by case in a particular link library dynamic { DLL), loaded in an address space of a random access memory. { RAM), both as part of a first task as part of a second task loaded in the address space of the RAM simultaneously, in a computer that has a memory management hardware, which includes a local descriptor table. { LDT) to bad selectors to the base addresses of the RAM, this method comprises: providing a task switching intensifier (the TSE) in the DLL; it provides in the TSE a routine of the registry of the DLL to register a DLL with the TSE, when this DLL is loaded; it provides in the particular DLL, a call to the registry routine of the DLL; provide in the TSE a routine to register the task, to register a task with the TSE, when this task is started; provide in the first task and in the second task a call to the task registration routine; provide in the TSE a routine that requires the operation system to supply the TSE with a notification of the commutation, when the execution of any task is about to begin or end, when any task is about to cease to exist; provide in the TSE a segment allocation routine to allocate a memory segment to store data per case of a DLL for a task, this assigned segment is a substitute for an original segment of data per case for that task, the segment original being referenced through a selector in the particular DLL that references an LDT entry, the segment assignment routine that maintains a substitute base address is a base address for the segment assigned at the LDT entry and maintains an original base address that is the original base address of the original segment at the LDT entry; call the TSE segment assignment routine for a particular data segment of the particular DLL for the first task during the initialization of the first task and call the TSE segment assignment routine for a data segment per case of the Particular DLL for the second task, during the initialization of the second task; provide in the TSE a routine for adjusting the base address to store in the LDT entry the substitute base address of a segment per case of a task, before that task begins to execute; and invoking the base address adjustment routine for the substitute base address for the first task, in response to a switch notification, received by the TSE that the first task is beginning execution.
  2. 2 . The method according to claim 1, further comprising: in response to a switching notification, received by the TSE, storing the original base address at the LDT entry for the segment by case of the Particular DLL, when no task linked to the Particular DLL is about to start its execution.
  3. 3. The method according to claim 1, further comprising: in response to a switching notification, received by the TSE, linking this TSE to another task registered by the TSE, if this TSE is linked to a task that is about to cease to exist .
  4. 4. The method according to claim 1, wherein: the operating system is selected from the group consisting of Microsoft® Windows 3.12 and Microsoft® Windows 3.11 and the computer is based on a microprocessor compatible with the Intel® 80386 microprocessor.
  5. 5. In the context of a multi-task operating system, provided for the loading of dynamic link libraries (DLL) in a random access memory (RAM) address space and the link of a DLL to multiple tasks loaded in the RAM address space simultaneously, and a computer that has a hardware memory address, which includes a local descriptor table (LDT) for the map of selectors to base addresses of the RAM, a set of components to supply the data memory per case for a Particular DLL, loaded as part of a first task as part of a second task, this set of components comprises: a task switching intensifier (TSE) of the DLL, which includes: a DLL registration routine, for register a DLL with the TSE, when this DLL is loaded; a task registration routine, to register a task with the TSE, when this task is initiated; a routine request from the operating system, to supply the TSE with a switch notification when the execution of any task is about to begin or end, and when any task is about to cease to exist; a segment allocation routine, to allocate a memory segment to store data per case of a DLL for a task, this assigned segment is a substitute for an original segment of data per case for that task, the original segment being referenced through a selector in the particular DLL, which references the entry of the LDT, the assignment routine the segment maintains a base substitute address, which is a base address for the segment assigned in the LDT entry and which maintains an original base address that is the original base address of the original segment at the LDT entry; and a base address adjustment routine, to store in the LDT entry the substitute base address of a segment per case of a task, before the execution of the task begins. Summary of the Invention A method for providing a data memory per case in a particular dynamic link library, loaded into a random access memory address space, either as part of a first task or as part of a second task , loaded in the address space simultaneously, on a computer that has a memory management hardware, which includes a local descriptor table for mapping the selectors to the base addresses. The method includes supplying a task switching intensifier (the TSE) to the DLL; supply in the TSE a routine for registering the DLL to register a DLL with the TSE; provide in the particular DLL a call to the DLL registration routine; provide a task registration routine in the TSE to record a task with the TSE; provide in the first task and in the second task a call of the routine of task registration, Provide a routine that requests the operating system to provide a notification of commutation, when it is going to begin or finish the execution of any task and when any task is about to cease to exist; provide in the TSE a segment allocation routine to allocate a memory segment to store data per case of a DLL for a task, as a substitute for an original segment of data per case for that task, and maintain a substitute base address which is a base address for the segment assigned at the LDT entry and maintain an original base address which is the original base address of the original segment at the LDT entry; call the assignment routine of the TSE segment for a data segment per case of a particular DLL for the first task, during the initialization of the first task and call the routing of the TSE segment assignment for a data segment per case of a particular DLL, for the second task, during the initiation of the second task; provide in the TSE a routine for adjusting the base address to store in the LDT entry the substitute base address of a segment per case of a task, before that task begins its execution; and invoking the adjustment routine of the base address for the substitute base address for the first task, in response to a switching notification received by the TSE, that the first task is about to begin its execution.
MXPA/A/1996/004437A 1995-09-29 1996-09-30 Dynamic switching of bibliot tasks MXPA96004437A (en)

Applications Claiming Priority (2)

Application Number Priority Date Filing Date Title
US08/537,235 US5802368A (en) 1995-09-29 1995-09-29 Dynamic Library Task Switching
US08537235 1995-09-29

Publications (2)

Publication Number Publication Date
MX9604437A MX9604437A (en) 1997-09-30
MXPA96004437A true MXPA96004437A (en) 1998-07-03

Family

ID=

Similar Documents

Publication Publication Date Title
US7143421B2 (en) Highly componentized system architecture with a demand-loading namespace and programming model
US7409694B2 (en) Highly componentized system architecture with loadable virtual memory manager
AU706491B2 (en) Dynamic library task switching
Litzkow et al. Checkpoint and migration of UNIX processes in the Condor distributed processing system
US5634058A (en) Dynamically configurable kernel
US8434099B2 (en) Efficient linking and loading for late binding and platform retargeting
US7565665B2 (en) Efficient linking and loading for late binding and platform retargeting
EP1763774B1 (en) Multiple computer architecture with replicated memory fields
US6917963B1 (en) Snapshot image for the application state of unshareable and shareable data
US6799173B2 (en) Method and apparatus for sharing code containing references to non-shared objects
US7415709B2 (en) Virtual resource ID mapping
EP0664903B1 (en) Loader system
US6728963B1 (en) Highly componentized system architecture with a loadable interprocess communication manager
US6154878A (en) System and method for on-line replacement of software
US5916308A (en) Dynamic link libraries without linker or loader support
US6199203B1 (en) Memory management techniques for on-line replaceable software
US20050262513A1 (en) Modified computer architecture with initialization of objects
US20090133042A1 (en) Efficient linking and loading for late binding and platform retargeting
Bozyigit et al. User-level process checkpoint and restore for migration
US7159222B1 (en) Highly componentized system architecture with object mutation
Bernabéu-Aubán et al. The architecture of Ra: a kernel for Clouds
MXPA96004437A (en) Dynamic switching of bibliot tasks
Clarke et al. Dynamic Memory Model Reconfiguration in DEIMOS
Lewis et al. Runtime Support for Automatic Wide Area Implementation Management in Legion.
AU2005236088A1 (en) Modified computer architecture with finalization of objects