// New returns a new Pigosat instance, ready to have literals added to it. The // error return value need only be checked if the OutputFile option is non-nil. func New(options *Options) (*Pigosat, error) { // PicoSAT * picosat_init (void); p := C.picosat_init() if options != nil { // void picosat_set_propagation_limit (PicoSAT *, unsigned long long limit); C.picosat_set_propagation_limit(p, C.ulonglong(options.PropagationLimit)) if options.OutputFile != nil { cfile, err := cfdopen(options.OutputFile, "a") if err != nil { C.picosat_reset(p) return nil, &os.PathError{Op: "fdopen", Path: options.OutputFile.Name(), Err: err} } // void picosat_set_output (PicoSAT *, FILE *); C.picosat_set_output(p, cfile) } // void picosat_set_verbosity (PicoSAT *, int new_verbosity_level); C.picosat_set_verbosity(p, C.int(options.Verbosity)) if options.Prefix != "" { // void picosat_set_prefix (PicoSAT *, const char *); prefix := C.CString(options.Prefix) defer C.free(unsafe.Pointer(prefix)) C.picosat_set_prefix(p, prefix) } if options.MeasureAllCalls { // void picosat_measure_all_calls (PicoSAT *); C.picosat_measure_all_calls(p) } } pgo := &Pigosat{p: p, lock: sync.RWMutex{}} runtime.SetFinalizer(pgo, (*Pigosat).delete) return pgo, nil }
// delete frees memory associated with p's PicoSAT object. It only needs to be // called from the runtime.SetFinalizer set in New. func (p *Pigosat) delete() { // For some reason, SetFinalizer needs delete to be idempotent/reentrant. // That said, since finalizers are only run when there are no more // references to the object, there doesn't seem to be any point in locking. if p.p == nil { return } // void picosat_reset (PicoSAT *); C.picosat_reset(p.p) p.p = nil }
// New returns a new Pigosat instance, ready to have literals added to it. The // error return value need only be checked if the OutputFile option is non-nil. func New(options *Options) (*Pigosat, error) { // PicoSAT * picosat_init (void); p := C.picosat_init() if options != nil { // void picosat_set_propagation_limit (PicoSAT *, unsigned long long limit); prop := options.PropagationLimit if prop == 0 { prop = 1000 } C.picosat_set_propagation_limit(p, C.ulonglong(prop)) if options.OutputFile != nil { cfile, err := cfdopen(options.OutputFile, "a") if err != nil { C.picosat_reset(p) return nil, &os.PathError{Op: "fdopen", Path: options.OutputFile.Name(), Err: err} } // void picosat_set_output (PicoSAT *, FILE *); C.picosat_set_output(p, cfile) } // void picosat_set_verbosity (PicoSAT *, int new_verbosity_level); C.picosat_set_verbosity(p, C.int(options.Verbosity)) if options.Prefix != "" { // void picosat_set_prefix (PicoSAT *, const char *); prefix := C.CString(options.Prefix) defer C.free(unsafe.Pointer(prefix)) C.picosat_set_prefix(p, prefix) } if options.MeasureAllCalls { // void picosat_measure_all_calls (PicoSAT *); C.picosat_measure_all_calls(p) } if options.EnableTrace { if int(C.picosat_enable_trace_generation(p)) == 0 { // The cgo CFLAGS guarantee trace generation using -DTRACE. panic("trace generation was not enabled in build") } } } pgo := &Pigosat{p: p, lock: sync.RWMutex{}} runtime.SetFinalizer(pgo, (*Pigosat).delete) return pgo, nil }