Subroutine LAPI_Util

Zweck

Dient als Wrapperfunktion für solche Datensammel-/Streuoperationen wie Registrierung und Reservierung, zum Aktualisieren von UDP-Portinformationen und zum Abrufen von Zeigern auf Sperren-und Signalisierungsfunktionen, die einer gemeinsam genutzten LAPI-Sperre zugeordnet sind.

Bibliothek

Verfügbarkeitsbibliothek (liblapi_r.a)

C-Syntax

#include <lapi.h>
 
int LAPI_Util(hndl, util_cmd)
lapi_handle_t hndl;
lapi_util_t *util_cmd;

FORTRAN-Syntax

include 'lapif.h'
 
LAPI_UTIL(hndl, util_cmd, ierror)
INTEGER hndl
TYPE (LAPI_UTIL_T) :: util_cmd
INTEGER ierror

Beschreibung

Type of call: Data Gather/Scatter Program (DGSP), UDP-Portinformationen und Dienstprogramme für die gemeinsame Nutzung von Sperren

Diese Subroutine wird für mehrere verschiedene Operationen verwendet, die durch den Befehlstypwert am Anfang der Befehlsstruktur angegeben werden. Die lapi_util_t -Struktur ist wie folgt definiert:
typedef union {
    lapi_util_type_t    Util_type;  
    lapi_reg_dgsp_t     RegDgsp;    
    lapi_dref_dgsp_t    DrefDgsp;   
    lapi_resv_dgsp_t    ResvDgsp;   
    lapi_reg_ddm_t      DdmFunc;    
    lapi_add_udp_port_t Udp;        
    lapi_pack_dgsp_t    PackDgsp;   
    lapi_unpack_dgsp_t  UnpackDgsp;
    lapi_thread_func_t  ThreadFunc;
} lapi_util_t;
Der Aufzählungstyp lapi_util_type_t hat die folgenden Werte:
Tabelle 1. lapi_util_type_t Typen
Wert von Util_type Union-Mitglied, wie von LAPI_Util interpretiert
LAPI_REGISTER_DGSP lapi_reg_dgsp_t
LAPI_UNRESERVE_DGSP lapi_dref_dgsp_t
LAPI_RESERVE_DGSP lapi_resv_dgsp_t
LAPI_REG_DDM_FUNC lapi_reg_ddm_t
LAPI_ADD_UDP_DEST_PORT lapi_add_udp_port_t
LAPI_DGSP_PACK lapi_pack_dgsp_t
LAPI_DGSP_UNPACK lapi_unpack_dgsp_t
LAPI_GET_THREAD_FUNC lapi_thread_func_t
hndl wird für den Befehlstyp LAPI_REGISTER_DGSP, LAPI_RESERVE_DGSPoder LAPI_UNRESERVE_DGSPnicht überprüft.

LAPI_REGISTER_DGSP

Sie können diese Operation zum Registrieren eines von Ihnen erstellten LAPI DGSP verwenden. Zum Registrieren eines LAPI DGSP muss lapi_dgsp_descr_t idgsp übergeben werden. LAPI gibt eine Kennung (lapi_dg_handle_t dgsp_handle) zurück, die für alle zukünftigen LAPI-Aufrufe verwendet werden soll. Die dgsp_handle , die von einer Registeroperation zurückgegeben wird, wird als lapi_dg_handle_t -Typ identifiziert. Dies ist der geeignete Typ für LAPI_Xfer -und LAPI_Util -Aufrufe, die einen DGSP verwenden. Diese zurückgegebene dgsp_handle ist auch für Situationen, in denen der LAPI-Benutzer Lesezugriff auf Informationen benötigt, die im zwischengespeicherten DGSP enthalten sind, als castable für einen Zeiger auf einen lapi_dgsp_descr_t definiert. Die Registrierungsoperation stellt eine DGSP an LAPI für die Verwendung in zukünftigen Operationen zum Senden, Empfangen, Packen und Entpacken von Nachrichten bereit. LAPI erstellt eine eigene Kopie des DGSP und schützt sie durch Referenzanzahl. Alle internen LAPI-Operationen, die von einem in LAPI zwischengespeicherten DGSP abhängen, stellen die Beibehaltung des DGSP sicher, indem die Referenzanzahl erhöht wird, wenn sie eine Abhängigkeit vom DGSP beginnen, und die Anzahl verringert wird, wenn diese Abhängigkeit endet. Ein DGSP kann nach der Registrierung von einer beliebigen LAPI-Instanz verwendet werden. LAPI_Term löscht keine DGSPs.

Sie können einen DGSP registrieren, eine oder mehrere LAPI-Operationen mit dem DGSP starten und dann die Reservierung aufheben, ohne zu bedenken, wann die LAPI-Operationen, die von dem DGSP abhängig sind, mit ihm ausgeführt werden. Weitere Informationen finden Sie unter LAPI_RESERVE_DGSP und LAPI_UNRESERVE_DGSP .

Im Allgemeinen wird der DGSP, den Sie erstellen und an den LAPI_REGISTER_DGSP -Aufruf übergeben, unter Verwendung des Parameters dgsp gelöscht, nachdem LAPI seine eigene Kopie erstellt und zwischengespeichert hat. Da die DGSP-Erstellung komplex ist, können Benutzerfehler auftreten, aber eine umfangreiche Fehlerprüfung zur Datenübertragungszeit würde die Leistung beeinträchtigen. Bei der Entwicklung von Code, der DGSPs erstellt, können Sie zum Zeitpunkt der Registrierung eine zusätzliche Validierung aufrufen, indem Sie die Umgebungsvariable LAPI_VERIFY_DGSP festlegen. LAPI_Util gibt alle erkannten Fehler zurück. Alle vorhandenen Fehler, die bei der Registrierung nicht erkannt werden, führen zu Problemen bei der Datenübertragung. Alle während der Datenübertragung festgestellten Fehler werden von einem asynchronen Fehlerbehandlungsprogramm gemeldet. Ein Segmentierungsfehler ist ein allgemeines Symptom eines fehlerhaften DGSP. Wenn mehrere DGSPs verwendet werden, kann die asynchrone Fehlerbehandlungsroutine nicht ermitteln, welcher DGSP den Fehler verursacht hat. Weitere Informationen zur asynchronen Fehlerbehandlung finden Sie unter LAPI_Init.

LAPI_REGISTER_DGSP verwendet die Befehlsstruktur lapi_reg_dgsp_t .
Tabelle 2. Die lapi_reg_dgsp_t-Felder
lapi_reg_dgsp_t, Feld lapi_reg_dgsp_t, Feldtyp lapi_reg_dgsp_t, Syntax
Utiltyp lapi_util_type_t LAPI_REGISTER_DGSP
IDGSS lapi_dgsp_descr_t IN-Zeiger auf DGSP-Programm
dgsp-kennung lapi_dg_handle_t OUT-Kennung für ein registriertes DGSP-Programm
in_usr_func lapi_usr_fcall_t Nur für Debugging
Status lapi_status_t OUT-Unterstützung für die Zukunft

LAPI_RESERVE_DGSP

Mit dieser Operation können Sie einen DGSP reservieren. Diese Operation wird bereitgestellt, weil ein LAPI-Client eine LAPI-DGSP-Kennung zur späteren Verwendung zwischenspeichern kann. Der Client muss sicherstellen, dass DGSP nicht gelöscht wird, bevor die zwischengespeicherte Kennung verwendet wird. Eine DGSP-Kennung, die als Zeiger auf eine DGSP-Beschreibung definiert ist, die bereits in LAPI zwischengespeichert ist, wird an diese Operation übergeben. Die DGSP-Kennung ist auch als Strukturzeiger definiert, sodass Clientprogramme direkten Zugriff auf Informationen in der DGSP erhalten. Wenn der Client nicht sicher ist, dass der DGSP nicht von einem anderen Thread "nicht reserviert" wird, während auf ihn zugegriffen wird, sollte der Client das Zugriffsfenster mit seiner eigenen Operation zum Reservieren/Aufheben der Reservierung zusammenhalten. Der Client soll den zwischengespeicherten DGSP nicht ändern, aber LAPI hat keine Möglichkeit, dies zu erzwingen. Die Reservierungsoperation erhöht den Benutzerreferenzzähler und schützt so das DGSP, bis eine Operation zum Aufheben der Reservierung auftritt. Dies ist erforderlich, weil der Thread, der die Reservierung vorgenommen hat, erwartet, dass er den zwischengespeicherten DGSP verwenden oder untersuchen kann, bis er einen Aufruf zum Aufheben der Reservierung ausführt (wodurch die Anzahl der Benutzerreferenzen verringert wird), selbst wenn die Operation zum Aufheben der Reservierung, die der ursprünglichen Registeroperation entspricht, in diesem Fenster in einem anderen Thread auftritt.

LAPI_RESERVE_DGSP verwendet die Befehlsstruktur lapi_resv_dgsp_t .
Tabelle 3. Felder 'lapi_resv_dgsp_t'
lapi_resv_dgsp_t, Feld lapi_resv_dgsp_t, Feldtyp lapi_resv_dgsp_t Syntax
Utiltyp lapi_util_type_t LAPI_RESERVE_DGSP
dgsp-kennung lapi_dg_handle_t OUT-Kennung für ein registriertes DGSP-Programm
in_usr_func lapi_usr_fcall_t Nur für Debugging
Status lapi_status_t OUT-Unterstützung für die Zukunft

LAPI_UNRESERVE_DGSP

Mit dieser Operation können Sie die Registrierung eines DGSP aufheben oder die Reservierung eines DGSP aufheben. Diese Operation verringert die Anzahl der Benutzerreferenzen. Wenn die Anzahl der externen und internen Referenzen null ist, lässt diese Operation die LAPI den DGSP freigeben. Alle Operationen, die einen Referenzzähler verringern, führen dazu, dass LAPI prüft, ob beide Zähler zu 0 geworden sind. Ist dies der Fall, wird der DGSP verworfen. Mehrere interne LAPI-Aktivitäten erhöhen und verringern einen zweiten Referenzzähler. Der zwischengespeicherte DGSP ist nur verfügbar, wenn alle Aktivitäten (intern und extern), die von ihm abhängig sind, und die Referenzzählung verwenden, um sie beizubehalten, ihre Referenz entladen haben. Die DGSP-Kennung wird als Wertparameter an LAPI übergeben und LAPI setzt die Kennung des aufrufenden Programms nicht auf null. Es liegt in Ihrer Verantwortung, diese Kennung nicht erneut zu verwenden, da Sie bei einer Operation zum Aufheben der Reservierung angegeben haben, dass Sie nicht mehr darauf zählen, dass die Kennung gültig bleibt.

LAPI_UNRESERVE_DGSP verwendet die Befehlsstruktur lapi_dref_dgsp_t .
Tabelle 4. Die lapi_dref_dgsp_t-Felder
lapi_dref_dgsp_t, Feld lapi_dref_dgsp_t, Feldtyp Verwendung von 'lapi_dref_dgsp_t'
Utiltyp lapi_util_type_t LAPI_UNRESERVE_DGSP
dgsp-kennung lapi_dg_handle_t OUT-Kennung für ein registriertes DGSP-Programm
in_usr_func lapi_usr_fcall_t Nur für Debugging
Status lapi_status_t OUT-Unterstützung für die Zukunft

LAPI_REG_DDM_FUNC

Mit dieser Operation können DDM-Funktionen (Data Distribution Manager) registriert werden. Es funktioniert in Verbindung mit der Anweisung DGSM CONTROL. Hauptsächlich wird sie für MPI_Accumulateverwendet, aber LAPI-Clients können jede DDM-Funktion bereitstellen. Es wird auch zum Einrichten einer Callback-Funktion für die Verarbeitung von Daten verwendet, die in einen Benutzerpuffer auf der Zielseite gestreut werden.

Der native LAPI-Benutzer kann einen Callback installieren, ohne dass sich dies auf die MPI-Registrierung für MPI_Accumulateauswirkt. Der Funktionsprototyp für die Callback-Funktion lautet:
typedef long ddm_func_t (        /* return number of bytes processed */
        void      *in,           /* pointer to inbound data          */
        void      *inout,        /* pointer to destination space     */
        long      bytes,         /* number of bytes inbound          */
        int       operand,       /* CONTROL operand value            */
        int       operation      /* CONTROL operation value          */
);

Eine DDM-Funktion agiert zwischen dem Eingang von Nachrichtendaten und dem Zielpuffer. Die häufigste Verwendung besteht darin, eingehende Daten mit Daten zu kombinieren, die sich bereits im Zielpuffer befinden. Wenn der Zielpuffer beispielsweise ein Array von ganzen Zahlen ist und die eingehende Nachricht aus ganzen Zahlen besteht, kann die DDM-Funktion geschrieben werden, um jede eingehende ganze Zahl zu dem Wert hinzuzufügen, der sich bereits im Puffer befindet. Die Felder operand und operation der DDM-Funktion ermöglichen einer DDM-Funktion, einen Bereich von Operationen mit der Anweisung CONTROL zu unterstützen, indem die entsprechenden Werte für diese Felder angegeben werden.

Weitere Informationen zur DGSP-Programmierung finden Sie in RSCT für AIX 5L: LAPI Programming Guide .

LAPI_REG_DDM_FUNC verwendet die Befehlsstruktur lapi_reg_ddm_t . Jeder Aufruf ersetzt den vorherigen Funktionszeiger, sofern vorhanden.
Tabelle 5. Die Felder 'lapi_reg_ddm_t'
lapi_reg_ddm_t, Feld lapi_reg_ddm_t, Feldtyp Syntax von lapi_reg_ddm_t
Utiltyp lapi_util_type_t LAPI_REG_DDM_FUNC
ddm-funktion ddm_func_t * IN-DDM-Funktionszeiger
in_usr_func lapi_usr_fcall_t Nur für Debugging
Status lapi_status_t OUT-Unterstützung für die Zukunft

LAPI_DGSP_PACK

Mit dieser Operation können Sie Daten aus einem Benutzerpuffer, der von einem DGSP gesteuert wird, in einem Packpuffer zusammenstellen. Ein einzelner Puffer kann durch mehrere Aufrufe gepackt werden. Der Aufrufende stellt einen Wert position bereit, der mit dem Anfangsoffset innerhalb des Puffers initialisiert wird. Jede Packoperation passt die Positionan, sodass die nächste Packoperation dort beginnen kann, wo die vorherige Packoperation beendet wurde. Im Allgemeinen beginnt eine Reihe von Packoperationen mit Position , initialisiert mit 0, aber jeder Offset ist gültig. Es wird kein Status von einer Packoperation zur nächsten übertragen. Jede Packoperation beginnt am Anfang des übergebenen DGSP.

LAPI_DGSP_PACK verwendet die Befehlsstruktur lapi_pack_dgsp_t .
Tabelle 6: Die Felder 'lapi_pack_dgsp_t'
Feld lapi_pack_dgsp_t Feldtyp lapi_pack_dgsp_t Syntax von lapi_pack_dgsp_t
Utiltyp lapi_util_type_t LAPI_DGSP_PACK
dgsp-kennung lapi_dg_handle_t OUT-Kennung für ein registriertes DGSP-Programm
in_buf void * IN-Quellenpuffer zum Packen
Byte ulong IN-Anzahl der zu packenden Bytes
Ausgabebuf void * OUT-Ausgabepuffer für Pack
out_size ulong IN-Ausgabepuffergröße in Byte
Position ulong IN/OUT-Aktuelle Pufferposition
in_usr_func lapi_usr_fcall_t Nur für Debugging
Status lapi_status_t OUT-Unterstützung für die Zukunft

LAPI_DGSP_UNPACK

Mit dieser Operation können Sie Daten aus einem gepackten Puffer in einen Benutzerpuffer streuen, der von einem DGSP gesteuert wird. Ein einzelner Puffer kann durch mehrere Aufrufe entpackt werden. Der Aufrufende stellt einen Wert für position bereit, der mit dem Anfangsoffset im gepackten Puffer initialisiert wird. Jede Entpackoperation passt die Positionan, sodass die nächste Entpackoperation an der Stelle beginnen kann, an der die vorherige Entpackoperation beendet wurde. Im Allgemeinen beginnt eine Reihe von Entpackoperationen mit Position , die mit 0initialisiert wurde, aber jeder Offset ist gültig. Es wird kein Status von einer Entpackoperation zur nächsten übertragen. Jede Entpackoperation beginnt am Anfang des übergebenen DGSP.

LAPI_DGSP_UNPACK verwendet die Befehlsstruktur lapi_unpack_dgsp_t .
Tabelle 7: Die lapi_unpack_dgsp_t-Felder
lapi_unpack_dgsp_t, Feld lapi_unpack_dgsp_t, Feldtyp Syntax von lapi_unpack_dgsp_t
Utiltyp lapi_util_type_t LAPI_DGSP_UNPACK
dgsp-kennung lapi_dg_handle_t OUT-Kennung für ein registriertes DGSP-Programm
buf void * IN-Quellenpuffer für Entpacken
in_size ulong IN-Quellenpuffergröße in Byte
Ausgabebuf void * OUT-Ausgabepuffer für Entpacken
Byte ulong IN-Anzahl der zu entpackenden Bytes
out_size ulong IN-Ausgabepuffergröße in Byte
Position ulong IN/OUT-Aktuelle Pufferposition
in_usr_func lapi_usr_fcall_t Nur für Debugging
Status lapi_status_t OUT-Unterstützung für die Zukunft

LAPI-ADD_UDP_DEST_PORT

Mit dieser Operation können Sie UDP-Portinformationen zur Zieltask aktualisieren. Diese Operation kann verwendet werden, wenn Sie einen eigenen UDP-Handler (udp_hndlr) geschrieben haben und die Wiederherstellung fehlgeschlagener Tasks unterstützen müssen. Sie können diese Operation nicht in der POE-Laufzeitumgebung verwenden.

LAPI_ADD_UDP_DEST_PORT verwendet die Befehlsstruktur lapi_add_udp_port_t .
Tabelle 8. Die Felder 'lapi_add_udp_port_t'
lapi_add_udp_port_t, Feld lapi_add_udp_port_t, Feldtyp lapi_add_udp_port_t, Syntax
Utiltyp lapi_util_type_t LAPI_ADD_UDP_DEST_PORT
tgt uint ID der IN-Zieltask
UDP-Port lapi_udp_t * IN-UDP-Portinformationen für das Ziel
Instanznummer uint IN-Instanznummer von UDP
in_usr_func lapi_usr_fcall_t Nur für Debugging
Status lapi_status_t OUT-Unterstützung für die Zukunft

LAPI-GET_THREAD_FUNC

Sie können diese Operation verwenden, um verschiedene Funktionen für gemeinsame Sperrung und Signalisierung abzurufen. Das Abrufen dieser Funktionen ist nur nach der Initialisierung von LAPI und vor der Beendigung von LAPI gültig. Sie sollten keine dieser Funktionen aufrufen, nachdem LAPI beendet wurde.

LAPI_GET_THREAD_FUNC verwendet die Befehlsstruktur lapi_thread_func_t .
Tabelle 9. Die Felder 'lapi_thread_func_t'
lapi_thread_func_t, Feld lapi_thread_func_t, Feldtyp Verwendung von 'lapi_thread_func_t'
Utiltyp lapi_util_type_t LAPI_GET_THREAD_FUNC
Mutex_Lock lapi_mutex_lock_t OUT-mutex lock Funktionszeiger
mutex_unlock lapi_mutex_unlock_t OUT-mutex unlock Funktionszeiger
mutex_trylock lapi_mutex_trylock_t OUT-mutex try lock Funktionszeiger
mutex_getowner lapi_mutex_getowner_t OUT-mutex get owner Funktionszeiger
cond_wait lapi_cond_wait_t OUT-Funktionszeiger condition wait
cond_timedwait lapi_cond_timedwait_t OUT- Bedingung timed wait Funktionszeiger
cond_signal lapi_cond_signal_t OUT- condition signal funktionszeiger
Kon_Initialisierung lapi_cond_init_t OUT-Initialisierungsbedingung Funktionszeiger
Löschen lapi_cond_destroy_t OUT-destroy-Bedingung Funktionszeiger

LAPI verwendet die pthread-Bibliothek für die Thread-ID-Verwaltung. Sie können daher pthread_self() verwenden, um die aktive Thread-ID abzurufen, und lapi_mutex_getowner_t , um die Thread-ID abzurufen, die Eigner der gemeinsamen Sperre ist. Anschließend können Sie mithilfe von pthread_equal() feststellen, ob beide identisch sind.

Mutex-Thread-Funktionen

LAPI_GET_THREAD_FUNC enthält die folgenden Mutex-Threadfunktionen: mutex lock, mutex unlock, mutex try lock und mutex get owner.

Mutex lock function pointer
int (*lapi_mutex_lock_t)(lapi_handle_t hndl);
Diese Funktion fordert die Sperre an, die der angegebenen LAPI-Kennung zugeordnet ist. Der Aufruf wird blockiert, wenn die Sperre bereits von einem anderen Thread gehalten wird. Ein Deadlock kann auftreten, wenn der aufrufende Thread die Sperre bereits hält. Sie sind für die Vermeidung und Erkennung von Deadlocks verantwortlich.
Parameters
INPUT
hndl
Gibt die LAPI-Kennung an.
Return values
0
Zeigt an, dass die Sperre erfolgreich angefordert wurde.
EINVAL
Wird zurückgegeben, wenn die Sperre aufgrund eines falschen Werts für hndl nicht gültig ist.
Mutex unlock function pointer
int (*lapi_mutex_unlock_t)(lapi_handle_t hndl);
Diese Funktion gibt die Sperre frei, die der angegebenen LAPI-Kennung zugeordnet ist. Ein Thread sollte nur seine eigenen Sperren entsperren.
Parameters
INPUT
hndl
Gibt die LAPI-Kennung an.
Return values
0
Zeigt an, dass die Sperre erfolgreich freigegeben wurde.
EINVAL
Wird zurückgegeben, wenn die Sperre aufgrund eines falschen Werts für hndl nicht gültig ist.
Mutex try lock function pointer
int (*lapi_mutex_trylock_t)(lapi_handle_t hndl);
Diese Funktion versucht, die Sperre anzufordern, die der angegebenen LAPI-Kennung zugeordnet ist, gibt aber sofort zurück, wenn die Sperre bereits gehalten wird.
Parameters
INPUT
hndl
Gibt die LAPI-Kennung an.
Return values
0
Zeigt an, dass die Sperre erfolgreich angefordert wurde.
EBUSY
Gibt an, dass die Sperre gehalten wird.
EINVAL
Wird zurückgegeben, wenn die Sperre aufgrund eines falschen Werts für hndl nicht gültig ist.
Mutex get owner function pointer
int (*lapi_mutex_getowner_t)(lapi_handle_t hndl, pthread_t *tid);
Diese Funktion ruft die pthread-ID des Threads ab, der momentan die Sperre hält, die der angegebenen LAPI-Kennung zugeordnet ist. LAPI_NULL_THREAD_ID gibt an, dass die Sperre nicht gehalten wird, wenn die Funktion aufgerufen wird.
Parameters
INPUT
hndl
Gibt die LAPI-Kennung an.
Ausgabe
tid
Ein Zeiger, der die abzurufende pthread-ID enthält.
Return values
0
Gibt an, dass der Sperreneigentümer erfolgreich abgerufen wurde
EINVAL
Wird zurückgegeben, wenn die Sperre aufgrund eines falschen Werts für hndl nicht gültig ist.

Bedingungsfunktionen

LAPI_GET_THREAD_FUNC enthält die folgenden Bedingungsfunktionen : condition wait, condition timed wait, condition signal, initialize condition und destroy condition.

Condition wait function pointer
int (*lapi_cond_wait_t)(lapi_handle_t hndl, lapi_cond_t *cond);
Diese Funktion wartet auf eine Bedingungsvariable (cond). Der Benutzer muss die Sperre halten, die dem LAPI-Handle (hndl) zugeordnet ist, bevor er den Aufruf ausführt. Nach der Rückgabe des Aufrufs garantiert LAPI, dass die Sperre weiterhin gehalten wird. Dieselbe LAPI-Kennung muss für gleichzeitige lapi_cond_wait_t -Operationen unter derselben Bedingungsvariablen bereitgestellt werden.
Parameters
INPUT
hndl
Gibt die LAPI-Kennung an.
cond
Zeiger auf die Bedingungsvariable, auf die gewartet werden soll.
Return values
0
Gibt an, dass die Bedingungsvariable signalisiert wurde.
EINVAL
Gibt an, dass der durch hndl oder cond angegebene Wert ungültig ist.
Condition timed wait function pointer
int (*lapi_cond_timedwait_t)(lapi_handle_t hndl, 
                             lapi_cond_t *cond, 
                             struct timespec *timeout);
Diese Funktion wartet auf eine Bedingungsvariable (cond). Der Benutzer muss die Sperre halten, die dem LAPI-Handle (hndl) zugeordnet ist, bevor er den Aufruf ausführt. Nach der Rückgabe des Aufrufs garantiert LAPI, dass die Sperre weiterhin gehalten wird. Dieselbe LAPI-Kennung muss für gleichzeitige lapi_cond_timedwait_t -Operationen unter derselben Bedingungsvariablen bereitgestellt werden.
Parameters
INPUT
hndl
Gibt die LAPI-Kennung an.
cond
Zeiger auf die Bedingungsvariable, auf die gewartet werden soll.
Zeitlimit
Ein Zeiger auf die absolute Zeitstruktur, die das Zeitlimit angibt.
Return values
0
Gibt an, dass die Bedingungsvariable signalisiert wurde.
EZEITDOUT
Gibt an, dass die durch timeout angegebene Zeit abgelaufen ist.
EINVAL
Gibt an, dass der durch hndl, condangegebene Wert oder timeout ist ungültig.
Condition signal function pointer
int (*lapi_cond_wait_t)(lapi_handle_t hndl, lapi_cond_t *cond);
typedef int (*lapi_cond_signal_t)(lapi_handle_t hndl, lapi_cond_t *cond);
Diese Funktion signalisiert eine Bedingungsvariable (cond), einen Thread zu aktivieren, der bei der Bedingung blockiert wird. Wenn mehrere Threads auf die Bedingungsvariable warten, wird nach dem Zufallsprinzip entschieden, welcher Thread aktiviert werden soll.
Parameters
INPUT
hndl
Gibt die LAPI-Kennung an.
cond
Ist ein Zeiger auf die Bedingungsvariable, die signalisiert werden soll.
Return values
0
Gibt an, dass die Bedingungsvariable signalisiert wurde.
EINVAL
Gibt an, dass der durch hndl oder cond angegebene Wert ungültig ist.
Initialize condition function pointer
int (*lapi_cond_init_t)(lapi_handle_t hndl, lapi_cond_t *cond);
Diese Funktion initialisiert eine Bedingungsvariable.
Parameters
INPUT
hndl
Gibt die LAPI-Kennung an.
cond
Ein Zeiger auf die zu initialisierende Bedingungsvariable.
Return values
0
Gibt an, dass die Bedingungsvariable erfolgreich initialisiert wurde.
EAGAIN
Gibt an, dass dem System die erforderlichen Ressourcen (außer Speicher) fehlten, um eine weitere Bedingungsvariable zu initialisieren.
ENOMEM
Gibt an, dass nicht genügend Speicher zum Initialisieren der Bedingungsvariablen vorhanden ist.
EINVAL
Wird zurückgegeben, wenn der Wert für hndl ungültig ist.
Destroy condition function pointer
int (*lapi_cond_destroy_t)(lapi_handle_t hndl, lapi_cond_t *cond);
Diese Funktion zerstört eine Bedingungsvariable.
Parameters
INPUT
hndl
Gibt die LAPI-Kennung an.
cond
Ein Zeiger auf die zu zerstörende Bedingungsvariable.
Return values
0
Gibt an, dass die Bedingungsvariable erfolgreich gelöscht wurde
EBUSY
Gibt an, dass die Implementierung einen Versuch erkannt hat, das von Cond referenzierte Objekt zu löschen, während es referenziert wird (z. B. bei Verwendung in einem lapi_cond_wait_t oder lapi_cond_timedwait_t durch einen anderen Thread).
EINVAL
Gibt an, dass der durch hndl oder cond angegebene Wert ungültig ist.

Parameter

INPUT
hndl
Gibt die LAPI-Kennung an.
Ein-/Ausgabe
Dienstprogrammbefehl
Gibt den Befehlstyp der Dienstprogrammfunktion an.
Ausgabe
ierror
Gibt einen FORTRAN-Rückkehrcode an Dies ist immer der letzte Parameter.

Rückgabewerte

LAPI_ERFOLG
Gibt an, dass der Funktionsaufruf erfolgreich ausgeführt wurde.
LAPI_ERR_DGSP
Gibt an, dass der übergebene DGSP NULL (in C) oder LAPI_ADDR_NULL (in FORTRAN) ist oder kein registrierter DGSP ist.
LAPI_ERR_DGSP_ATOM
Gibt an, dass der DGSP eine atomgröße hat, die kleiner als 0 oder größer als MAX_ATOM_SIZE ist.
LAPI_ERR_DGSP_BRANCH
Gibt an, dass der DGSP versucht hat, eine Verzweigung auszuführen, die außerhalb des Code-Arrays liegt. Dies wird nur im Validierungsmodus zurückgegeben.
LAPI_ERR_DGSP_COPY_SZ
Wird mit aktivierter DGSP-Validierung zurückgegeben, wenn MCOPY-Block < 0 oder COPY-Anweisung mit Byte < 0ist. Dies wird nur im Validierungsmodus zurückgegeben.
LAPI_ERR_DGSP_FREI
Gibt an, dass LAPI versucht hat, einen DGSP freizugeben, der ungültig oder nicht mehr registriert ist. Es sollte eine LAPI_UNRESERVE_DGSP -Operation zum Schließen der LAPI_REGISTER_DGSP -Operation und eine LAPI_UNRESERVE_DGSP -Operation für jede LAPI_RESERVE_DGSP -Operation vorhanden sein.
LAPI_ERR_DGSP_OPC
Gibt an, dass der DGSP- Operationscode nicht gültig ist. Dies wird nur im Validierungsmodus zurückgegeben.
LAPI_ERR_DGSP_STACK
Gibt an, dass der DGSP eine größere GOSUB-Tiefe hat als der zugeordnete Stack unterstützt. Die Stapelzuordnung wird durch das Member dgsp->depth angegeben. Dies wird nur im Validierungsmodus zurückgegeben.
LAPI_ERR_HNDL_UNGÜLTIG
Gibt an, dass die übergebene hndl ungültig ist (nicht initialisiert oder beendet).
LAPI_ERR_MEMORY_ERSCHÖPFT
Gibt an, dass LAPI keinen Speicher vom System abrufen kann.
LAPI_ERR_UDP_PORT_INFO
Gibt an, dass der Informationszeiger udp_port NULL ist (in C) oder dass der Wert von udp_port LAPI_ADDR_NULL ist (in FORTRAN).
LAPI_ERR_UTIL_CMD
Gibt an, dass der Befehlstyp ungültig ist.

C-Beispiele

  1. Gehen Sie wie folgt vor, um einen DGSP zu erstellen und zu registrieren:
    
    {
          /*
          ** DGSP code array.  DGSP instructions are stored
          ** as ints (with constants defined in lapi.h for
          ** the number of integers needed to store each
          ** instruction).  We will have one COPY and one ITERATE
          ** instruction in our DGSP.  We use LAPI's constants
          ** to allocate the appropriate storage.
          */
          int code[LAPI_DGSM_COPY_SIZE+LAPI_DGSM_ITERATE_SIZE];
    
          /* DGSP description */
          lapi_dgsp_descr_t dgsp_d;
    
          /*
          ** Data structure for the xfer call.
          */
          lapi_xfer_t   xfer_struct;
    
       
          /* DGSP data structures */
          lapi_dgsm_copy_t     *copy_p;   /* copy instruction    */
          lapi_dgsm_iterate_t  *iter_p;   /* iterate instruction */
          int                  *code_ptr; /* code pointer        */
    
          /* constant for holding code array info */
          int                   code_less_iterate_size;
    
          /* used for DGSP registration */
          lapi_reg_dgsp_t     reg_util;
    
    
          /*
          ** Set up dgsp description
          */
    
          /* set pointer to code array */
          dgsp_d.code = &code[0];
    
          /* set size of code array */
          dgsp_d.code_size = LAPI_DGSM_COPY_SIZE + LAPI_DGSM_ITERATE_SIZE;
    
          /* not using DGSP gosub instruction */
          dgsp_d.depth = 1;
    
          /*
          ** set density to show internal gaps in the
          ** DGSP data layout
          */
          dgsp_d.density = LAPI_DGSM_SPARSE;
    
          /* transfer 4 bytes at a time */
          dgsp_d.size = 4;
    
          /* advance the template by 8 for each iteration */
          dgsp_d.extent = 8;
    
          /*
          ** ext specifies the memory 'footprint' of
          ** data to be transferred. The lext specifies
          ** the offset from the base address to begin
          ** viewing the data.  The rext specifies the
          ** length from the base address to use.
          */
          dgsp_d.lext = 0;
          dgsp_d.rext = 4;
          /* atom size of 0 lets LAPI choose the packet size */
          dgsp_d.atom_size = 0;
    
          /*
          ** set up the copy instruction
          */
          copy_p = (lapi_dgsm_copy_t *)(dgsp_d.code);
          copy_p->opcode = LAPI_DGSM_COPY;
    
          /* copy 4 bytes at a time */
          copy_p->bytes = (long) 4;
    
          /* start at offset 0 */
          copy_p->offset = (long) 0;
    
          /* set code pointer to address of iterate instruction */
          code_less_iterate_size =  dgsp_d.code_size - LAPI_DGSM_ITERATE_SIZE;
          code_ptr = ((int *)(code))+code_less_iterate_size;
    
          /*
          ** Set up iterate instruction
          */
          iter_p = (lapi_dgsm_iterate_t *) code_ptr;
          iter_p->opcode = LAPI_DGSM_ITERATE;
          iter_p->iter_loc = (-code_less_iterate_size);
    
          /* Set up and do DGSP registration */
          reg_util.Util_type = LAPI_REGISTER_DGSP;
          reg_util.idgsp = &dgsp_d;
          LAPI_Util(hndl, (lapi_util_t *)&reg_util);
    
          /* 
          ** LAPI returns a usable DGSP handle in 
          ** reg_util.dgsp_handle
          ** Use this handle for subsequent reserve/unreserve
          ** and Xfer calls.  On the receive side, this
          ** handle can be returned by the header handler using the 
          ** return_info_t mechanism.  The DGSP will then be used for
          ** scattering data.
          */
          
    }
    
  2. Gehen Sie wie folgt vor, um eine DGSP-Kennung zu reservieren:
    
    {
    	
          reg_util.dgsp_handle = dgsp_handle;
    
          /* 
          ** dgsp_handle has already been created and
          ** registered as in the above example
          */
    
          reg_util.Util_type = LAPI_RESERVE_DGSP;
          LAPI_Util(hndl, (lapi_util_t *)&reg_util);
    
          /*
          ** LAPI's internal reference count to dgsp_handle
          ** will be incremented.  DGSP will
          ** remain available until an unreserve is
          ** done for each reserve, plus one more for
          ** the original registration.
          */
    
    }
    
  3. Gehen Sie wie folgt vor, um die Reservierung einer DGSP-Kennung aufzuheben:
    
    {
    	
          reg_util.dgsp_handle = dgsp_handle;
    
          /* 
          ** dgsp_handle has already created and
          ** registered as in the above example, and
          ** this thread no longer needs it.
          */
    
          reg_util.Util_type = LAPI_UNRESERVE_DGSP;
          LAPI_Util(hndl, (lapi_util_t *)&reg_util);
    
          /*
          ** An unreserve is required for each reserve,
          ** plus one more for the original registration.
          */
    
    }
    

location

/usr/lib/liblapi_r.a

Referenzinformationen

Subroutinen LAPI_Init, LAPI_Xfer