B. Procedur wejścia dla funkcji biblioteki uruchomieniowej
Ta sekcja zawiera procedur wejścia dla funkcji biblioteki uruchomieniowej zdefiniowane w OpenMP C i C++ API.Procedury wejścia są dostarczane do umożliwienia przenośności platform, które nie obsługują OpenMP C i C++ API.Na tych platformach OpenMP programy muszą być połączone z biblioteki, zawierającego te funkcje skrótowych.Funkcje skrótowej założono, że dyrektyw w programie OpenMP są ignorowane.Jako takie emulować one semantykę szeregowego.
[!UWAGA]
Zmienna blokady, która pojawia się w funkcji blokady musi być dostępny wyłącznie poprzez te funkcje.Nie nazwy jej być zainicjowana lub modyfikować w inny sposób w programie użytkownika.Użytkownicy, nie należy wprowadzać założenia dotyczące mechanizmów używanych przez implementacje OpenMP C i C++ do implementacji blokady, na podstawie schematu używanego przez funkcje skrótowych.
Kod
#include <stdio.h>
#include <stdlib.h>
#include "omp.h"
#ifdef __cplusplus
extern "C" {
#endif
void omp_set_num_threads(int num_threads)
{
}
int omp_get_num_threads(void)
{
return 1;
}
int omp_get_max_threads(void)
{
return 1;
}
int omp_get_thread_num(void)
{
return 0;
}
int omp_get_num_procs(void)
{
return 1;
}
void omp_set_dynamic(int dynamic_threads)
{
}
int omp_get_dynamic(void)
{
return 0;
}
int omp_in_parallel(void)
{
return 0;
}
void omp_set_nested(int nested)
{
}
int omp_get_nested(void)
{
return 0;
}
enum {UNLOCKED = -1, INIT, LOCKED};
void omp_init_lock(omp_lock_t *lock)
{
*lock = UNLOCKED;
}
void omp_destroy_lock(omp_lock_t *lock)
{
*lock = INIT;
}
void omp_set_lock(omp_lock_t *lock)
{
if (*lock == UNLOCKED)
{
*lock = LOCKED;
}
else
if (*lock == LOCKED)
{
fprintf_s(stderr, "error: deadlock in using lock variable\n");
exit(1);
} else {
fprintf_s(stderr, "error: lock not initialized\n");
exit(1);
}
}
void omp_unset_lock(omp_lock_t *lock)
{
if (*lock == LOCKED)
{
*lock = UNLOCKED;
}
else
if (*lock == UNLOCKED)
{
fprintf_s(stderr, "error: lock not set\n");
exit(1);
} else {
fprintf_s(stderr, "error: lock not initialized\n");
exit(1);
}
}
int omp_test_lock(omp_lock_t *lock)
{
if (*lock == UNLOCKED)
{
*lock = LOCKED;
return 1;
} else if (*lock == LOCKED) {
return 0;
} else {
fprintf_s(stderr, "error: lock not initialized\n");
exit(1);
}
}
#ifndef OMP_NEST_LOCK_T
typedef struct { // This really belongs in omp.h
int owner;
int count;
} omp_nest_lock_t;
#endif
enum {MASTER = 0};
void omp_init_nest_lock(omp_nest_lock_t *lock)
{
lock->owner = UNLOCKED;
lock->count = 0;
}
void omp_destroy_nest_lock(omp_nest_lock_t *lock)
{
lock->owner = UNLOCKED;
lock->count = UNLOCKED;
}
void omp_set_nest_lock(omp_nest_lock_t *lock)
{
if (lock->owner == MASTER && lock->count >= 1)
{
lock->count++;
} else
if (lock->owner == UNLOCKED && lock->count == 0)
{
lock->owner = MASTER;
lock->count = 1;
} else
{
fprintf_s(stderr, "error: lock corrupted or not initialized\n");
exit(1);
}
}
void omp_unset_nest_lock(omp_nest_lock_t *lock)
{
if (lock->owner == MASTER && lock->count >= 1)
{
lock->count--;
if (lock->count == 0)
{
lock->owner = UNLOCKED;
}
} else
if (lock->owner == UNLOCKED && lock->count == 0)
{
fprintf_s(stderr, "error: lock not set\n");
exit(1);
} else
{
fprintf_s(stderr, "error: lock corrupted or not initialized\n");
exit(1);
}
}
int omp_test_nest_lock(omp_nest_lock_t *lock)
{
omp_set_nest_lock(lock);
return lock->count;
}
double omp_get_wtime(void)
{
// This function does not provide a working
// wallclock timer. Replace it with a version
// customized for the target machine.
return 0.0;
}
double omp_get_wtick(void)
{
// This function does not provide a working
// clock tick function. Replace it with
// a version customized for the target machine.
return 365. * 86400.;
}
#ifdef __cplusplus
}
#endif