Multi-threading Compiler Directives |
This chapter describes the set of COBOL system library routines available for use in multi-threading applications.
The COBOL system library routines use type definitions and COBOL CALL prototypes; this helps you to ensure that all calls to these routines to be valid. For further information see the section Using the Library Routine TYPEDEFs and CALL Prototypes in the chapter Library Routines in your Programmer's Guide to Writing Programs.
To ensure that the type definitions and CALL protoypes are used by your program, you should include the copyfile $COBDIR/cpylib/cblproto.cpy in your program. cblproto.cpy must be copied before the Identificaton Division of the program being compiled.
Call-by-name library routines provide a programming interface through which you can implement and control multi-threading in your applications. Library routines are provided for:
All of the routines return a value in RETURN-CODE, which is a data item specified as cblt-rtncode.
Creates a thread from a named entry point |
|
Creates a thread from a procedure pointer |
|
Detaches a non-detached thread |
|
Terminates the current thread |
|
Allocates an ID-data area for a thread |
|
Gets a pointer to an ID-data area |
|
Kills a thread |
|
Ends thread-list processing |
|
Gets next thread in thread-list |
|
Starts thread-list processing |
|
Locks functions of thread-handling routines |
|
Locks a thread |
|
Unlocks a thread |
|
Resumes a suspended thread |
|
Suspends a thread |
|
Stores the thread identifier of a thread |
|
Causes a thread to relinquish control of the CPU |
|
Unlocks locked thread-handling routines |
|
Waits for a non-detached thread to complete |
|
Yields a thread's timeslice |
The following values are provided as RETURN-CODE values from the thread-control routines:
0 | No error was encountered. |
1000 | Memory allocation error. |
1001 | The thread identifier is invalid. No operations are valid on this thread. It is possible that the thread identifier specified was once valid but it has already terminated and detached. |
1002 | The thread identifier has been detached and terminated. No operations are valid on this thread. |
1003 | The thread is detached. CBL_THREAD_DETACH cannot detach the thread since it has already been detached. CBL_THREAD_WAIT cannot wait on the thread since it has already been detached. |
1004 | Too many threads. CBL_THREAD_CREATE cannot create another thread since too many threads exist in the system already. |
1005 | The stack size is invalid. CBL_THREAD_CREATE cannot create this thread as the operating system will not allow the provided stack size to be used. |
1006 | Invalid operation. CBL_THREAD_CREATE cannot create a thread while the system is deinitializing. An invalid thread-control routine was attempted on a thread that was not created with CBL_THREAD_CREATE. CBL_THREAD_PROG_LOCK was not called directly or indirectly from a COBOL program. |
1007 | System error. An unknown system error caused this function to fail. |
1008 | Threading not supported in this run-time system. A threaded application attempted to use the routines through a non-threaded run-time system. |
1009 | Invalid parameter. A parameter has been detected that is not within the valid range, or that is inconsistent with the routine. |
1011 | Program or entry-point name not found. The program or entry-point name specified to CBL_THREAD_CREATE was not found, or there was an error loading it. |
Mutexes, semaphores, monitors and events can be used to synchronize threads. Synchronization objects are named, and the name is visible throughout the system, not just in the creating process.
Clears the specified event. |
|
Closes the supplied event handle |
|
Creates an intra-process event |
|
Posts the specified event |
|
Waits for the event to be posted |
Events can be used for thread synchronization within the same process.
Events are implemented where possible by calling the operating system directly, thus they give lower level functionality than monitors.
An event is a synchronization object which can be posted and cleared by different threads. A thread may wait for an event to become posted; if there are several threads waiting when the event becomes posted, all the threads are then allowed to continue.
Acquires browse capability for a thread |
|
Converts browse capability to read capability |
|
Converts browse capability to write capability |
|
Closes the supplied monitor handle |
|
Creates a monitor |
|
Acquires read capability |
|
Releases lock applied to the specified monitor |
|
Releases browse capability |
|
Releases read capability |
|
Releases write capability |
|
Acquires write capability |
|
Converts monitor write capability to browse |
A monitor is a synchronization object which can be locked for read, browse, and write operations. This type of synchronization is typically used to protect a data structure in which different threads might want to read and write.
A monitor can only be used as an intra-process synchronization object.
Any monitors created or opened using the library routines are automatically closed when the run-time system terminates (for example, as a consequence of a STOP RUN).
A write lock locks out all other read, browse, and write locks. Typically, a write lock is used when writing to the data structure.
A browse lock locks out other write and browse locks, but allows simultaneous read locks. Typically, a browse lock is used when reading a data structure with a view to writing to it depending on the results of the read. To this end, a function is provided to convert a browse lock to a write lock without letting in any other writers.
A read lock only locks out write locks. Typically, a read lock is used when reading a data structure without any intention of writing to it.
A thread that has acquired a read lock on a particular monitor might acquire another read lock on the same monitor. However, when a read lock has been acquired, the thread may not request a browse or write lock, unless an "outer" browse or write lock exists in which the read lock is nested. Any attempt to break this rule will result in a run-time system error. When interleaved priority is requested on a monitor it is possible that a nested read lock will block waiting for a writer to finish his request, but since the first read lock is still active, the writer will never be granted write access - this is single thread deadlock. If you expect nested read locks to be obtained then either use reader priority or obtain a write or browse lock at the highest level of locking.
A thread that has acquired a browse lock on a particular monitor may acquire another browse lock on the same monitor. It may also acquire a write lock. It may also acquire a read lock, as long as that read lock is released before the original browse lock is converted into a write lock, and before any write lock is requested.
A thread that has acquired a write lock on a particular monitor may also acquire another write, browse or read lock on the same monitor.
Acquires a mutex |
|
Closes the specified mutex |
|
Creates an intra-process mutex |
|
Releases the specified mutex |
Mutexes can be used for thread synchronization within the same process.
Mutexes are implemented where possible by calling the operating system directly, thus they give lower-level functionality than monitors.
A mutex is a synchronization object which at any one time zero or one thread "owns". If a thread has acquired a mutex, and another thread requests it, depending on a "wait" option, the second thread either returns without acquiring the mutex, or blocks until the first thread has released it. If several threads are blocked waiting for the mutex, only one of them is unblocked; all the others continue to wait.
Acquires one of the resources represented by the semaphore |
|
Closes a semaphore |
|
Creates an intra-process semaphore |
|
Releases one of the resources represented by the semaphore |
Semaphores can be used for thread synchronization within the same process.
A semaphore is a synchronization object which has a count associated with it, typically representing the available number of some limited resource. A thread acquires one of these resources by using the acquire call; if none of the resources is available, the call either blocks or returns with an error depending on a "wait" option. If a resource is available (the count is non-zero), the count is decremented and the call returns with no error.
A thread releases a resource using the release call, which increments the count; if other threads are blocked because no resources are available (the count is zero), one of them is released. The others remain blocked because in the process of releasing the first one, the count is decremented back to zero.
The following values are provided as RETURN-CODE values from the synchronization routines:
0 | No error was encountered. |
1000 | Memory allocation error. |
1001 | The handle is invalid. The handle is not a valid handle for the synchronization object, and no operations are valid on it. It is possible that the handle specified was once valid but it has been closed and memory reused. |
1002 | The handle has been closed. No operations are valid on this handle. The handle was once valid but has since been closed. |
1007 | A system error was encountered. The last operation caused a system error in low-level object manipulation. |
1008 | Threading not supported in this run-time system. A threaded application attempted to use a multi-threading routine while running with a non-threaded run-time system. |
1009 | Invalid parameter passed into a multi-threading library routine. A parameter has been detected as being out of valid ranges or inconsistent with the library routine. |
1010 | No resources available. A semaphore or
mutex cannot be acquired because its count is zero and the
program requested no automatic wait.
or: An event is not posted and the program has no wait on the CBL_EVENT_WAIT call. |
The easiest way to handle thread-local data is to use a Thread-Local-Storage Section in your program. It is assumed that you understand the concept of thread-local data.
Library routines are also provided to give you control over the way in which thread-specific data is handled. These routines enable your program to:
Deallocates thread-storage area |
|
Creates a thread-storage area |
|
Gets a pointer to a thread-storage area |
You can allocate thread-local data from the dynamic heap via CBL_ALLOC_MEM or the modular CBL_ALLOC_THREAD_MEM. The advantage of this form of allocation is that multiple memory blocks of varying sizes can be allocated and associated with a thread and/or program.
CBL_ALLOC_MEM can associate allocated heap data with a thread and the calling program, depending on the setting of the input parameters. CBL_ALLOC_THREAD_MEM always associates any allocated heap data with a thread, and optionally the calling program.
Memory allocated by these routines is automatically cleaned up when the thread terminates.
Note that any pointer to thread-local storage returned by these calls should be saved in a pointer defined in the Thread-Local-Storage Section, so that its value can be retrieved on subsequent calls to the program that allocated the thread-local storage area. Saving the returned pointer in a pointer defined in the Working-Storage Section and subsequently using that value causes the thread-local heap area to be shared among threads and is bad programming practice.
Routines are supplied that enable a program to access thread-local data from an initialized thread-storage handle. This handle is returned by the CBL_TSTORE_CREATE routine. Memory is returned by CBL_TSTORE_GET using a specific handle. The memory is of a fixed size and is the same across all invocations of CBL_TSTORE_GET within that thread. These routines provide, in essence, a distinct thread-local-storage area for each initialized handle.
The following example program initializes a thread-storage handle and
then starts off several threads which each use the handle to access thread
local data. Consistency checks are made within each entry to ts-test
on termination of each thread and on termination of the run-unit. This
program takes advantage of the Thread-Local-Storage Section, external data
items, exit procedures and basic synchronization to achieve this function.
$set reentrant sourceformat(free) copy "cblproto.cpy". ************************************************************ * tstore-main. * * Main routine to initialize tables and kick off threads. * * * ************************************************************ program-id. 'tstore'. environment division. special-names. command-line is cmdln. working-storage section. 78 THREAD-COUNT VALUE 5. 01 tstore-handle cblt-pointer is external. 01 c-0 cblt-x1-compx. 01 foo-item pic 9(9) value 0. 01 thredid pic xxxx comp-5. 01 thread-handle cblt-pointer. 01 thread-entry cblt-ppointer. 01 exitparms cblt-exit-params. thread-local-storage section. 01 filler. 05 tl-count pic x value 'x'. 05 tl-ptr cblt-pointer. linkage section. 01 tstore-item. 05 filler pic x. 88 TSTORE-INIT VALUE 'Y'. 05 tstore-count pic 999. procedure division. *> *> Initialize thread table and set up for clean exit *> call "CBL_TSTORE_CREATE" using tstore-handle by value length tstore-item by value h'04' *> *> Set up for clean exit *> move low-values to exitparms set cblt-ep-install-addr to entry 'exitproc' move 0 to c-0 call 'CBL_EXIT_PROC' using c-0 exitparms call 'ts-get' using tl-ptr set address of tstore-item to tl-ptr move THREAD-COUNT to tstore-count set thread-entry to entry "ts-entry" move 1 to thredid perform THREAD-COUNT times call "CBL_THREAD_CREATE_P" using by value thread-entry by reference thredid by value length of thredid by value 0 by value 0 by value 0 by reference thread-handle if return-code not = 0 call 'CBL_THREAD_PROG_LOCK' display "FAIL: Cannot create thread" call 'CBL_THREAD_PROG_UNLOCK' stop run end-if add 1 to thredid end-perform stop run. entry "exitproc". call "CBL_TSTORE_GET" using by value tstore-handle by reference tl-ptr set address of tstore-item to tl-ptr if tl-ptr = NULL or not TSTORE-INIT or tstore-count not = THREAD-COUNT display "FAIL: TSTORE not initialized properly!" else display "PASS: Main thread has count " tstore-count end-if call "CBL_TSTORE_CLOSE" using by value tstore-handle exit program. end program 'tstore'. ************************************************************ * * * ts-entry. * * Root entry point for threads created by application. * * * ************************************************************ program-id. 'ts-entry'. working-storage section. 78 REP-COUNT VALUE 5. 01 tl-ptr cblt-pointer. linkage section. 01 lnk-thredid pic xxxx comp-5. 01 tstore-item. 05 filler pic x. 88 TSTORE-INIT VALUE 'Y'. 05 tstore-count pic 999. procedure division using lnk-thredid. thread-section. perform REP-COUNT times call 'ts-test' using lnk-thredid end-perform call 'ts-get' using tl-ptr set address of tstore-item to tl-ptr call "CBL_THREAD_PROG_LOCK" if tstore-count not = REP-COUNT display "FAIL: Thread storage rep-count BAD" else display "PASS: Thread storage rep-count good" end-if call "CBL_THREAD_PROG_UNLOCK" exit program. end program 'ts-entry'. ************************************************************ * * * ts-test. * * Routine to get a thread storage area and increment its * * count * * * ************************************************************ program-id. 'ts-test'. working-storage section. 01 global-count pic 99999 value 0. thread-local-storage section. 01 tl-ptr cblt-pointer. 01 tl-count pic 999 value 0. linkage section. 01 lnk-thredid pic xxxx comp-5. 01 tstore-item. 05 filler pic x. 88 TSTORE-INIT VALUE 'Y'. 05 tstore-count pic 999. procedure division using lnk-thredid. thread-section. call 'ts-get' using tl-ptr set address of tstore-item to tl-ptr add 1 to tstore-count add 1 to tl-count if tstore-count not = tl-count display "ERROR: inconsistent thread local data" stop run end-if call "CBL_THREAD_PROG_LOCK" add 1 to global-count display "MESSAGE: thread-test has been called " tstore-count " by thread " lnk-thredid display "MESSAGE: thread-test has been called " global-count " globally " call "CBL_THREAD_PROG_UNLOCK" exit program. end program 'ts-test'. ************************************************************ * ts-get. * * Common routine to get and initialize the thread storage * * area allocated by CBL_TSTORE_GET. * * * ************************************************************ program-id. 'ts-get'. data division. working-storage section. 01 tstore-handle cblt-pointer external. thread-local-storage section. 01 tl-ptr cblt-pointer. linkage section. 01 tstore-item. 05 filler pic x. 88 TSTORE-INIT VALUE 'Y'. 05 tstore-count pic 999. 01 lnk-ptr usage pointer. procedure division using lnk-ptr. call "CBL_TSTORE_GET" using by value tstore-handle by reference tl-ptr if tl-ptr = NULL display "FAIL: Error in getting thread " & "storage data" stop run end-if set address of tstore-item to tl-ptr if not TSTORE-INIT move 0 to tstore-count end-if set tstore-init to true set lnk-ptr to tl-ptr exit program. end program 'ts-get'.
The following values are provided as RETURN-CODE values from the thread-control routines:
0 | No error was encountered. |
1000 | Memory allocation error. |
1001 | Thread-storage handle is invalid. No operations are valid on this thread-storage handle. It is possible that the handle specified was once valid but it has been closed and the memory reused. |
1002 | Thread-storage handle is invalid.The thread storage handle has previously been closed and is no longer valid. |
1009 | Invalid parameter passed into a thread-specific data-handling library routine. A parameter has been detected as being out of valid ranges or inconsistent with the library routine. |
1010 | Resource busy. A synchronization object was still locked upon thread termination and when the thread was created the program requested an error to be reported if this condition occurred. |
You can allocate thread-specific heap memory using CBL_ALLOC_THREAD_MEM. You can free this memory using CBL_FREE_THREAD_MEM.
Allocates thread-specific heap memory |
|
Frees allocated thread-specific heap memory |
Descriptions for all of the call-by-name routines appear alphabetically. Each description contains the routine name and function followed by these sections (as appropriate):
Syntax: | Shows the CALL statement you
could use to call the routine.
The optional RETURNING clause is also shown. Every routine returns a value showing the result of the operation. Unless otherwise indicated, zero indicates success, nonzero indicates failure. This value is left in the data item specified in the RETURNING clause, in this reference, status-code. If this clause is omitted, the value is left in the special register RETURN-CODE. (If call-convention bit two is set, RETURN-CODE is not changed.) The name of the routine must be coded in upper case. |
Parameters: | Describes any parameters shown in the RETURNING and USING clause. A parameter enclosed in brackets, for example, [parameter1] is optional and might not be needed for all forms of the routine. |
On Entry: | Indicates which of the parameters shown
are passed on entry |
On Exit: | Indicates which of the
parameters shown are returned on exit.
Where bits of one or more bytes are referenced, bit 0 is the least significant (rightmost) bit. |
Comments: | Provides any additional information necessary for the successful use of the routine |
See also: | Lists other related topics. |
The routines are listed in alphabetical order.
Allocates thread-specific heap memory.
call "CBL_ALLOC_THREAD_MEM" using mem-pointer by value mem-size by value flags returning status-code
mem-pointer |
cblt-pointer. |
mem-size |
cblt-os-size. |
flags |
cblt-os-flags. |
status-code |
See Key |
mem-size |
Size of memory to be allocated. | ||||||
flags |
The type of memory required. You can set the following
bits:
|
mem-pointer |
A pointer to the memory allocated. The allocated memory is not initialized. | ||||||
status-code |
|
If bit 2 is not set the memory allocated by CBL_ALLOC_THREAD_MEM is freed when the program that allocated it is cancelled (logically or physically), if there is a COBOL program that is directly or indirectly the caller.
If bit 2 is set, this memory is freed when the thread that allocated it terminates, if it has not been previously freed by CBL_FREE_THREAD_MEM.
Clears the specified event.
call "CBL_EVENT_CLEAR" using by value event-handle
event-handle |
cblt-pointer. |
event-handle |
The event handle. |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
The routine has no effect if the event was already clear.
Behavior is undefined if event-handle
is invalid.
Closes the supplied event handle.
call "CBL_EVENT_CLOSE" using by value event-handle
event-handle |
cblt-pointer. |
event-handle |
The event handle. |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
The event is destroyed.
Behavior is undefined if event-handle
is invalid.
Creates an intra-process event.
call "CBL_EVENT_OPEN_INTRA" using by reference event-handle by value open-flags
event-handle |
cblt-pointer. |
open-flags |
cblt-os-flags. |
open-flags |
A 32-bit number specifying how the event is to be created:
|
event-handle |
The event handle |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
event-handle
is local to the process.
Posts the specified event.
call "CBL_EVENT_POST" using by value event-handle
event-handle |
cblt-pointer. |
event-handle |
The event handle. |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
If any threads are waiting for the event to be posted in the CBL_EVENT_WAIT call, they are all allowed to run and hence return from their CBL_EVENT_WAIT calls. The call has no effect if the event was already posted. The call returns zero for success.
Behavior is undefined if event-handle
is invalid.
Waits for the event to be posted.
call "CBL_EVENT_WAIT" using by value event-handle by value nowait-flag
event-handle |
cblt-pointer. |
nowait-flag |
cblt-os-flags. |
event-handle |
The event handle. | |||||||||
nowait-flag |
A 32-bit number that specifies the action to take if
the event has not been posted:
|
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
If the event is already posted, the call returns immediately.
Frees dynamically allocated thread-specific heap memory.
call "CBL_FREE_THREAD_MEM" using by value mem-pointer returning status-code
mem-pointer |
cblt-pointer. |
status-code |
See Key |
mem-pointer |
The pointer returned when the memory was allocated using CBL_ALLOC_THREAD_MEM. |
None
This routine releases memory allocated by the CBL_ALLOC_THREAD_MEM routine.
Acquires the specified monitor's browse capability for the current thread, blocking until that capability can be acquired.
call "CBL_MONITOR_BROWSE" using by value monitor-handle
monitor-handle |
cblt-pointer. |
monitor-handle |
The monitor handle. |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
If the thread terminates abnormally, all monitors acquired by that thread are released. If the thread terminates normally with monitors acquired, then either these are released or a run-time system error is given, depending on the flag setting when the thread was created with CBL_THREAD_CREATE.
Behavior is undefined if monitor-handle
is
invalid.
Converts monitor browse capability already acquired by the current thread to read capability.
call "CBL_MONITOR_BROWSE_TO_READ" using by value monitor-handle
monitor-handle |
cblt-pointer. |
monitor-handle |
The monitor handle. |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
Behavior is undefined if:
monitor-handle
is invalid.Converts monitor browse capability already acquired by the current thread to write capability, blocking until this can be achieved.
call "CBL_MONITOR_BROWSE_TO_WRITE" using by value monitor-handle
monitor-handle |
cblt-pointer. |
monitor-handle |
The monitor handle. |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
Behavior is undefined if:
monitor-handle
is invalid.Closes the supplied monitor handle.
call "CBL_MONITOR_CLOSE" using by value monitor-handle
monitor-handle |
cblt-pointer. |
monitor-handle |
The monitor handle. |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
If this process is the last process that has a handle to the monitor, then the monitor is destroyed.
Behavior is undefined if monitor-handle
is
invalid.
Creates a monitor synchronization object for thread synchronization within one process.
call "CBL_MONITOR_OPEN_INTRA" using by reference monitor-handle by value open-flags
monitor-handle |
cblt-pointer. |
open-flags |
cblt-os-flags. |
open-flags |
A 32-bit word indicating the priority algorithm used
to grant locks:
|
monitor-handle |
The monitor handle. |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
If open-flags
bit 0 is set to 0, and nested read
locks are requested, then single thread deadlock is possible.
Acquires the specified monitor's read capability for the current thread/process, blocking until that capability can be acquired.
call "CBL_MONITOR_READ" using by value monitor-handle
monitor-handle |
cblt-pointer. |
monitor-handle |
The monitor handle. |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
If the thread terminates abnormally, all monitors acquired by that thread are released. If the thread terminates normally with monitors acquired, then either these are released or a run-time system error is given, depending on the flag setting when the thread was created with CBL_THREAD_CREATE.
Behavior is undefined if monitor-handle
is
invalid.
Releases any lock applied to the specified monitor by a CBL_MONITOR_WRITE, CBL_MONITOR_READ or CBL_MONITOR_BROWSE.
call "CBL_MONITOR_RELEASE" using by value monitor-handle
monitor-handle |
cblt-pointer. |
monitor-handle |
The monitor handle. |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
If the thread terminates abnormally, all monitors acquired by that thread are released. If the thread terminates normally with monitors acquired, then either these are released or a run-time system error is given, depending on the flag setting when the thread was created with CBL_THREAD_CREATE.
Behavior is undefined if monitor-handle
is
invalid.
Releases the monitor's browse capability that was acquired by CBL_MONITOR_BROWSE or CBL_MONITOR_WRITE_TO_BROWSE.
call "CBL_MONITOR_UNBROWSE" using by value monitor-handle
monitor-handle |
cblt-pointer. |
monitor-handle |
A space-terminated or null-terminated monitor name. |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
Behavior is undefined if:
monitor-handle
is invalid.Releases the monitor's read capability that was acquired by CBL_MONITOR_READ or CBL_MONITOR_BROWSE_TO_READ.
call "CBL_MONITOR_UNREAD" using by value monitor-handle
monitor-handle |
cblt-pointer. |
monitor-handle |
A space-terminated or null-terminated monitor name. |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
Behavior is undefined if:
monitor-handle
is invalid.Releases the monitor's write capability that was acquired by CBL_MONITOR_WRITE or CBL_MONITOR_BROWSE_TO_WRITE.
call "CBL_MONITOR_UNWRITE" using by value monitor-handle
monitor-handle |
cblt-pointer. |
monitor-handle |
A space-terminated or null-terminated monitor name. |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
Behavior is undefined if:
monitor-handle
is invalid.Acquires the specified monitor's write capability for the current thread, blocking until that capability can be acquired.
call "CBL_MONITOR_WRITE" using by value monitor-handle
monitor-handle |
cblt-pointer. |
monitor-handle |
A space-terminated or null-terminated monitor name. |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
If the thread terminates abnormally, all monitors acquired by that thread are released. If the thread terminates normally with monitors acquired, then either these are released or a run-time system error is given, depending on the flag setting when the thread was created.
Behavior is undefined if monitor-handle
is
invalid.
Converts monitor write capability already acquired by the current thread to browse capability.
call "CBL_MONITOR_WRITE_TO_BROWSE" using by value monitor-handle
monitor-handle |
cblt-pointer. |
monitor-handle |
A space-terminated or null-terminated monitor name. |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
Behavior is undefined if:
monitor-handle
is invalid.Acquires a mutex for the specified thread.
call "CBL_MUTEX_ACQUIRE" using by value mutex-handle by value nowait-flag
mutex-handle |
cblt-pointer. |
nowait-flag |
cblt-os-flags |
mutex-handle |
Mutex handle | ||||||||||||
|
A 32-bit number that determines what happens if the
mutex cannot be acquired immediately:
|
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
Behavior is undefined if mutex-handle
is invalid.
Closes the specified mutex.
call "CBL_MUTEX_CLOSE" using by value mutex-handle
mutex-handle |
cblt-pointer. |
mutex-handle |
Mutex handle |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
The mutex is destroyed.
Behavior is undefined if mutex-handle
is invalid.
Creates an intra-process mutex.
call "CBL_MUTEX_OPEN_INTRA" using by reference mutex-handle by value open-flags
mutex-handle |
cblt-pointer. |
open-flags |
cblt-os-flags. |
open-flags |
A 32-bit number that determines how the mutex is to be
opened:
|
mutex-handle |
Mutex handle |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
mutex-handle
is local to the process.
Releases the specified mutex.
call "CBL_MUTEX_RELEASE" using by value mutex-handle
mutex-handle |
cblt-pointer. |
mutex-handle |
Mutex handle |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
If one or more threads are blocked in a CBL_MUTEX_ACQUIRE routine waiting for this mutex, one of them unblocks and returns from its call with the mutex acquired.
Behavior is undefined if:
mutex-handle
is invalid.Acquires one of the resources represented by the semaphore by decrementing the associated count.
call "CBL_SEMAPHORE_ACQUIRE" using by value semaphore-handle by value nowait-flag
semaphore-handle |
cblt-pointer. |
nowait-flag |
cblt-os-flags |
semaphore-handle |
Semaphore handle. | ||||||||||||
nowait-flag |
A 32-bit value that determines the action of the
routine if the count is zero:
|
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
Behavior is undefined if semaphore-handle
is
invalid.
Closes the specified semaphore.
call "CBL_SEMAPHORE_CLOSE" using by value semaphore-handle
semaphore-handle |
cblt-pointer. |
semaphore-handle |
Semaphore handle. |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
The semaphore is destroyed.
Behavior is undefined if semaphore-handle
is
invalid.
Creates an intra-process semaphore.
call "CBL_SEMAPHORE_OPEN_INTRA" using by reference semaphore-handle
by value semaphore-start
by value open-flags
semaphore-handle |
cblt-pointer. |
semaphore-start |
cblt-x4-comp5. |
open-flags |
cblt-os-flags. |
semaphore-start |
Initial count for the semaphore. |
open-flags |
Reserved. Should be set to zero. |
semaphore-handle |
Semaphore handle. |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
None.
Releases one of the resources represented by the semaphore by incrementing the associated count.
call "CBL_SEMAPHORE_RELEASE" using by value semaphore-handle
semaphore-handle |
cblt-pointer. |
semaphore-handle |
Semaphore handle. |
return-code |
A value of 0 indicates that the call was successful. Any other value indicates an error. See RETURN-CODE Values For Synchronization Routines |
If the count was zero before the increment, and some other threads are blocked in a CBL_SEMAPHORE_ACQUIRE call waiting for the count to become non-zero, then one of those threads is released, so it can decrement the count and return from CBL_SEMAPHORE_ACQUIRE.
Behavior is undefined if semaphore-handle
is
invalid.
Creates a thread from a named entry point.
call "CBL_THREAD_CREATE" using by reference entry-name by reference thread-param by value param-size by value flags by value priority by value stack-size by reference thread-id
entry-name |
pic x(n) space or null terminated |
thread-param |
pic x(n) space or null terminated |
param-size |
cblt-os-size. |
flags |
cblt-os-flags. |
priority |
cblt-sx4-comp5. |
stack-size |
cblt-os-size. |
thread-id |
cblt-pointer. |
entry-name |
Space or null terminated name for the thread | ||||||||||||||||||||||||||||||
thread-param |
Parameter passed to the new thread | ||||||||||||||||||||||||||||||
param-size |
|
||||||||||||||||||||||||||||||
flags |
A 32-bit number, in which the bits can be set as
follows:
|
||||||||||||||||||||||||||||||
priority |
Sets the priority. Normally, the priority is in the
range -100 to+100 and is relative to the current thread's priority.
Values of -1 and +1 indicate the smallest decrement/increment that give
the thread a lower/higher priority than the caller (unless the caller
already has the lowest/highest possible priority). If a
negative/positive value would take the thread's priority lower/higher
than is possible, then the lowest/highest value is used. If bit 1 of
flags is set to 1, then the priority is an
absolute value 0 to 100. |
||||||||||||||||||||||||||||||
stack-size |
Tells the run-time system how big a stack to give the new thread. A value of 0 causes a sensible default to be used. If the parameter appears to be invalid, the run-time system will either ignore it, or return an error indicating an invalid value was provided. |
thread-id |
A thread identifier. |
return-code |
A value indicating success or otherwise. See RETURN-CODE Values For Thread-control Routines |
The entry point specified can be implemented in any language.
If the call succeeds and a new thread is created, its thread identifier
is stored in thread-id
and the RETURN-CODE is set to
0. This is true even if the thread is created detached, however in this
case the caller should take care to ensure that the new thread still
exists before using the thread-id in any other call.
If the call fails thread-id
is set to NULL and an
error number is set in RETURN-CODE.
Creates a thread from a named entry point.
call "CBL_THREAD_CREATE_P" using by reference entry-point
by reference thread-param
by value param-size
by value flags
by value priority
by value stack-size
by reference thread-id
entry-point |
cblt-pointer. |
thread-param |
pic x(n) space or null terminated |
param-size |
cblt-os-size. |
flags |
cblt-os-flags. |
priority |
cblt-sx4-comp5. |
stack-size |
cblt-os-size. |
thread-id |
cblt-pointer. |
entry-name |
Procedure-pointer set to the appropriate entry point of program to execute | ||||||||||||||||||||||||||||||
thread-param |
Parameter passed to the new thread | ||||||||||||||||||||||||||||||
param-size |
|
||||||||||||||||||||||||||||||
flags |
A 32-bit number, in which the bits can be set as
follows:
|
||||||||||||||||||||||||||||||
priority |
Sets the priority. Normally, the priority is in the
range -100 to+100 and is relative to the current thread's priority.
Values of -1 and +1 indicate the smallest decrement/increment that give
the thread a lower/higher priority than the caller (unless the caller
already has the lowest/highest possible priority). If a
negative/positive value would take the thread's priority lower/higher
than is possible, then the lowest/highest value is used. If bit 1 of
flags is set to 1, then the priority is an
absolute value 0 to 100. |
||||||||||||||||||||||||||||||
stack-size |
Tells the run-time system how big a stack to give the new thread. A value of 0 causes a sensible default to be used. If the parameter appears to be invalid, the run-time system will either ignore it, or return an error indicating an invalid value was provided. |
thread-id |
A thread identifier. |
return-code |
A value indicating success or otherwise. See RETURN-CODE Values For Thread-control Routines |
The entry point specified can be implemented in any language.
If the call succeeds and a new thread is created, its thread identifier
is stored in thread-id
and the RETURN-CODE is set to
0. This is true even if the thread is created detached, however in this
case the caller should take care to ensure that the new thread still
exists before using the thread-id in any other call.
If the call fails thread-id
is set to NULL and an
error number is set in RETURN-CODE.
Frees thread resources when the thread terminates.
call "CBL_THREAD_DETACH" using by value thread-id
thread-id |
cblt-pointer. |
thread-id |
A pointer to the thread identifier. |
return-code |
A value indicating success or otherwise. See RETURN-CODE Values For Thread-control Routines. |
CBL_THREAD_DETACH enables a thread's resource to be freed when that thread terminates. When a thread is created (non-detached) a handle is returned to the creator. That handle can be used to wait for a thread, retrieve a return-code from the thread, inspect a thread's state, and so on. If a thread terminates, that handle is still valid until a WAIT or DETACH is done; that is, resources are still allocated to the (terminated) thread. If a thread is detached then all resources from a terminated thread are freed immediately; if the thread is still active those resources are marked to be freed when the thread terminates.
Behavior is undefined if:
thread-id
is undefined If successful, RETURN-CODE is set to 0. If unsuccessful, the call will attempt to return an error number. However, because some behaviors are undefined, a call that fails could result in a run-time system error.
Terminates the current thread.
call "CBL_THREAD_EXIT" using by value return-value
return-value |
cblt-pointer. |
None.
return-value |
Value returned from the thread processing |
return-code |
A value indicating success or otherwise. See RETURN-CODE Values For Thread-control Routines. |
In a thread created by CBL_THREAD_CREATE, this call
has the same effect as executing STOP RUN RETURNING return-value
from a COBOL program, or cobexit() from a program in another language.
This function can also be called from a program in another programming
language, in preference to using cobexit().
This call will fail, returning an error code, if the current thread was not created with CBL_THREAD_CREATE.
Allocates an ID-data area for the current thread.
CBL_THREAD_IDDATA_ALLOC using by reference iddata by value iddatasize
iddata |
cblt-pointer. |
iddatasize |
cblt-os-size. |
iddata |
ID-data area for the current thread |
iddatasize |
Size of the ID-data area. If it is zero, the thread will have no ID-data area. |
return-code |
A value indicating success or otherwise. See RETURN-CODE Values For Thread-control Routines. |
This call allocates an ID-data area for the current thread, and registers it so that a further call to CBL_THREAD_IDDATA_GET with this thread's handle will return the pointer to this data area. A call to CBL_THREAD_LIST_START or CBL_THREAD_LIST_NEXT can also be used to retrieve the pointer to this data area.
If there was already an ID-data area for this thread, the old one is freed and replaced by the new one. This will not happen if the call fails; typically this will occur if there is not enough memory to allocate the new ID-data area.
If the iddata
parameter is
passed as 'by value 0' then any area allocated is initialized to
low-values. Otherwise iddata
provides the
initialization data for the memory area allocated.
Returns a pointer to the ID-data area for the specified thread.
call "CBL_THREAD_IDDATA_GET" using by reference iddata-ptr by value thread-id
iddata-ptr |
cblt-pointer. |
thread-id |
cblt-pointer. |
iddata-ptr |
Pointer to the ID-data area for the specified thread |
thread-id | Pointer to the thread identifier |
return-code |
A value indicating success or otherwise. See RETURN-CODE Values For Thread-control Routines |
Returns a pointer to the ID-data area for the specified thread or NULL if no ID-data area has been allocated to date.
thread-id
might be NULL, in which case a pointer
to the current thread's ID-data area is returned.
If another thread's ID-data area is retrieved by this function you should make sure that any attempts to access it in all threads are protected by some form of locking (for example, by using CBL_THREAD_LOCK and CBL_THREAD_UNLOCK to frame all accesses to it).
Kills the specified thread, terminating it abnormally and detaching all resources associated with it.
call "CBL_THREAD_KILL" using by value thread-id
thread-id |
cblt-pointer. |
thread-id |
A pointer to the thread identifier |
return-code |
A value indicating success or otherwise. See RETURN-CODE Values For Thread-control Routines |
This routine can only be used to kill a thread that was created with CBL_THREAD_CREATE, and not threads created in other ways.
If the target thread has already completed, but was not detached, this call simply detaches it and discards any return value.
This call can be used with thread-id
set to the
current thread. In this case its effect is the same as CBL_THREAD_EXIT
with a NULL return value.
Behavior is undefined:
thread-id
is invalid Used, in conjunction with CBL_THREAD_LIST_START and CBL_THREAD_LIST_NEXT to obtain a list of all currently existing threads that the run-time system knows about. It is required to terminate a CBL_THREAD_LIST_START.
call "CBL_THREAD_LIST_END"
None.
return-code |
A value indicating success or otherwise. See RETURN-CODE Values For Thread-control Routines |
If unsuccessful, this routine returns an error number in RETURN-CODE. However, because some behaviors are undefined, a call to this routine that fails can result in a run-time system error.
Used, in conjunction with CBL_THREAD_LIST_START and CBL_THREAD_LIST_END to obtain a list of all currently existing threads that the run-time system knows about. The CBL_THREAD_LIST_NEXT call takes returns the next item in the list of threads.
call "CBL_THREAD_LIST_NEXT" using by reference thread-id by reference thread-state by reference thread-iddata
thread-id |
cblt-pointer. |
thread-state | cblt-x4-compx. |
thread-iddata | cblt-pointer. |
None
thread-id |
First thread identifier in this routine's internal list | |||||||||||||||
thread-state |
The state of the thread:
|
|||||||||||||||
thread-iddata |
A pointer to the thread's ID-data, if that data area exists (otherwise NULL). ID-data is specified by the routine CBL_THREAD_IDDATA_ALLOC. | |||||||||||||||
return-code |
A value indicating success or otherwise. See RETURN-CODE Values For Thread-control Routines |
Only information on existing threads, that is, threads that have not
terminated, is returned. This routine will not return a thread-id
for a thread that has terminated but has not been detached.
If thread-id
is NULL then the first item in the
list is returned (but there must have been a previous CBL_THREAD_LIST_START
call).
Behavior is undefined if thread-id
is invalid.
Used, in conjunction with CBL_THREAD_LIST_NEXT and CBL_THREAD_LIST_END to obtain a list of all currently existing threads that the run-time system knows about.
call "CBL_THREAD_LIST_START" using by reference thread-id by reference thread-state by reference thread-iddata
thread-id |
cblt-pointer. |
thread-state |
cblt-x4-compx. |
thread-iddata |
cblt-pointer. |
None.
thread-id |
First thread identifier in this routine's internal list | |||||||||||||||
thread-state |
The state of the thread:
|
|||||||||||||||
thread-iddata |
A pointer to the thread's ID-data, if that data area exists (otherwise NULL). ID-data is specified by the routine CBL_THREAD_IDDATA_ALLOC. | |||||||||||||||
return-code |
A value indicating success or otherwise. See RETURN-CODE Values For Thread-control Routines |
Only information on existing threads, that is, threads that have not
terminated, is returned. This routine will not return a thread-id
for a thread that has terminated but has not been detached.
Locks most functions of the thread-handling routines.
call "CBL_THREAD_LOCK"
None.
return-code |
A value indicating success or otherwise. See RETURN-CODE Values For Thread-control Routines |
This routine can also be used to synchronize access to global or external data, ID-data and error handling.
Any thread that obtains a CBL_THREAD_LOCK must not exit before doing a CBL_THREAD_UNLOCK.
With CBL_THREAD_PROG_UNLOCK, provides a single pre-initialized synchronization object per calling COBOL program
call "CBL_THREAD_PROG_LOCK"
None.
None.
return-code |
A value indicating success or otherwise. See RETURN-CODE Values For Thread-control Routines |
This function, in conjunction with CBL_THREAD_PROG_UNLOCK, provides a single pre-initialized synchronization object per calling COBOL program. This makes it especially useful for initializing any program local data items or synchronization objects.
These functions must be called either directly or indirectly from a COBOL program. The calling COBOL program is the one with which the lock is associated.
The following code at the entry to a program ensures that only the first thread entering a program will initialize data and all following threads will have that preinitialized data available:
if first-time = 0 call "cbl_thread_prog_lock" if first-time = 0 initialize my-data-division move 1 to first-time end-if call "cbl_thread_prog_unlock" end-if
Note the double check of the first-time variable. The first check is an optimization that avoids the overhead of locking the program if we know for sure that it has already been initialized.
With CBL_THREAD_PROG_LOCK, provides a single pre-initialized synchronization object per calling COBOL program
call "CBL_THREAD_PROG_UNLOCK"
None.
return-code |
A value indicating success or otherwise. See RETURN-CODE Values For Thread-control Routines |
This function, in conjunction with CBL_THREAD_PROG_LOCK, provides a single pre-initialized synchronization object per calling COBOL program. This makes it especially useful for initializing any program local data items or synchronization objects.
These functions must be called either directly or indirectly from a COBOL program. The calling COBOL program is the one with which the lock is associated.
The following code at the entry to a program ensures that only the first thread entering a program will initialize data and all following threads will have that preinitialized data available:
if first-time = 0 call "cbl_thread_prog_lock" if first-time = 0 initialize my-data-division move 1 to first-time end-if call "cbl_thread_prog_unlock" end-if
Note the double check of the first-time
variable. The
first check is an optimization that avoids the overhead of locking the
program if we know for sure that it has already been initialized.
Resumes a thread that was or will be suspended by CBL_THREAD_SUSPEND.
call "CBL_THREAD_RESUME" using by value thread-id
thread-id |
cblt-pointer. |
thread-id |
A pointer to the thread identifier |
return-code |
A value indicating success or otherwise. See RETURN-CODE Values For Thread-control Routines |
If the specified thread is suspended when a call to this routine is made, then RETURN-CODE is set to 0. If the specified thread was not suspended then the RETURN-CODE is set to the negative value of the number of times the target thread will have to call CBL_THREAD_SUSPEND before its execution is actually suspended.
Behavior is undefined if thread-id
is invalid.
Stores the thread identifier of the current thread.
call "CBL_THREAD_SELF" using by reference thread-id
thread-id |
cblt-pointer. |
thread-id |
A pointer to the thread identifier. |
return-code |
A value indicating success or otherwise. See RETURN-CODE Values For Thread-control Routines |
The run-time system returns the thread identifier and stores it in
thread-id
.
You can check that the run-time system under which your program is running supports multi-threading by a call to CBL_THREAD_SELF.
call 'cbl_thread_self' using thread-id on exception *>> no cbl_thread api support end-call if return-code == 1008 *>> running in a single threaded only rts end-if
Causes the calling thread to give up control to the processor for the given number of milliseconds.
call "CBL_THREAD_SLEEP" using by value milliseconds
milliseconds |
cblt-os-size. |
milliseconds |
Number of milliseconds |
return-code |
There is no valid return code from this function; this parameter is set to a random value. |
If the operating system does not support the yielding of a thread at millisecond granularity, then the units are scaled to a granularity that the operating system supports. The scaling is performed with rounding to the nearest unit supported by the operating system.
Suspends the current thread.
call "CBL_THREAD_SUSPEND" using by value thread-id
thread-id |
cblt-pointer. |
thread-id |
A pointer to the thread identifier |
return-code |
A value indicating success or otherwise. See RETURN-CODE Values For Thread-control Routines |
If thread-id
is NULL or is the current thread,
this routine suspends the current thread until another thread does a
CBL_THREAD_RESUME on it. If successful, RETURN-CODE
is set to 0. If one or more CBL_THREAD_RESUME routines have already
targetted this thread then RETURN-CODE is set to the negative value of the
number of further times CBL_THREAD_SUSPEND will have to be called before
the thread is actually suspended.
Otherwise, the call returns a non-zero (positive) error code.
You cannot suspend threads other than the current thread.
Behavior is undefined if thread-id
is invalid.
Unlocks most functions of the thread handling routines.
call "CBL_THREAD_UNLOCK"
None.
return-code |
A value indicating success or otherwise. See RETURN-CODE Values For Thread-control Routines |
This routine can also be used to synchronize access to global or external data, ID-data and error handling.
Any thread that obtains a CBL_THREAD_LOCK must not exit before doing a CBL_THREAD_UNLOCK.
Waits for completion of the specified non-detached thread, or returns immediately if the thread has already completed.
call "CBL_THREAD_WAIT" using by value thread-id by reference return-value
thread-id |
cblt-pointer. |
return-value |
cblt-pointer. |
thread-id |
A pointer to the thread identifier. |
return-value |
The thread's return value. See RETURN-CODE Values For Thread-control Routines. |
The behavior of this routine is undefined if:
thread-id
is invalid. thread-id
specifies a previously detached
thread. If the routine is successful, the thread's return value is stored in
return-value
, the target thread is detached, and the
call returns 0.
Yields the rest of the current thread's timeslice.
call "CBL_THREAD_YIELD"
None.
return-value |
The thread's return value. See RETURN-CODE Values For Thread-control Routines. |
If possible this routine yields to other threads in the same process, but might yield to a thread in a different process.
Closes a handle returned by CBL_TSTORE_CREATE.
call "CBL_TSTORE_CLOSE" using by value tstore-handle
tstore-handle |
cblt-pointer. |
tstore-handle |
The thread-storage handle. |
This routine closes a handle to a thread-storage area that was returned by CBL_TSTORE_CREATE, freeing all allocated memory for all threads.
Create a handle for and specifies the size of a thread-storage area. These values can be used in subsequent calls to CBL_TSTORE_GET.
call "CBL_TSTORE_CREATE" using tstore-handle by value tstore-size by value tstore-flags
tstore-handle |
cblt-pointer. |
tstore-size |
cblt-os-size. |
tstore-flags |
cblt-os-flags. |
tstore-size |
Size of thread-storage area that will be returned to every thread that calls CBL_TSTORE_GET using the returned handle. | ||||||||||||||||||
tstore-flags |
The type of thread-storage area required:
|
tstore-handle |
The thread-storage handle. | ||||
return-code |
Indicates success or otherwise of the routine:
|
CBL_TSTORE_CREATE specifies the size of the memory block that will be returned by any subsequent calls to CBL_TSTORE_GET and, optionally, associates that handle with the calling program so that when the calling program is canceled the returned handle is automatically closed. In any event the returned handle will be closed at termination of the run-unit or a call to CBL_TSTORE_CLOSE, whichever comes first.
If this thread-storage handle is not associated with a program, then the thread-storage handle is closed at the end of the run-unit.
You should ensure that this routine is called in single-threaded mode by forcing single-threaded behavior within a monitor lock, or by calling it only when initializing the application in single-threaded mode.
Gets a pointer to the thread-specific memory specified by CBL_TSTORE_CREATE.
call "CBL_TSTORE_GET" using by value tstore-handle tstore-ptr
tstore-handle |
cblt-pointer. |
tstore-ptr | cblt-pointer. |
tstore-handle |
A non-null handle. This is the handle returned by CBL_TSTORE_CREATE. |
tstore-ptr |
A pointer to a memory block of the size specified by CBL_TSTORE_CREATE. This pointer is unique to this thread. | ||||||||
return-code |
Indicates success or otherwise of the routine:
|
Returns a pointer to a block of memory of the size specified by CBL_TSTORE_CREATE. This pointer is unique for each calling thread.
A value is returned in RETURN-CODE, indicating success or otherwise of the routine:
Behavior is undefined if event-handle
is invalid.
Copyright © 2000 MERANT International Limited. All rights reserved.
This document and the proprietary marks and names
used herein are protected by international law.
Multi-threading Compiler Directives |